<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

        • 死磕javascript的手寫(xiě)面試題

          2021-4-15    前端達(dá)人

          1.實(shí)現(xiàn)lodash的_.get方法

          function _getValue(target, valuePath, defalutVal) {
            let valueType = Object.prototype.toString.call(target)
            console.log(valueType)
            // if (valueType == "[object Array]") {
              let paths = valuePath.replace(/\[(\d+)\]/, `.$1`).split('.')
              let result = target
              for(const path of paths){
                result = Object(result)[path]
                if(result == undefined){
                  return defalutVal
                }
              }
              return result
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          測(cè)試:
          let obj = {
            a:{
              b:[
                {
                  c:2
                }
              ]
            }
          }
          
          console.log(_getValue(obj, 'a.b[0].c')) //2 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          2.寫(xiě)一個(gè)函數(shù)判斷兩個(gè)變量是否相等

          function isEqual(res1, res2) {
            let a = getTypeOf(res1)
            let b = getTypeOf(res2)
            if(a !== b){
              return false
            }else if(a === 'base'){
              console.log('base',res1,res2)
              return res1 === res2
            } else if(a === 'array'){
              if(res1.length !== res2.length){
                console.log('array',res1,res2)
                return false
              }else{
                //遍歷數(shù)組的值比較
                for(let i =0;i<res1.length;i++){
                  if(!isEqual(res1[i],res2[i])){
                    console.log('array',res1[i],res2[i])
                    return false
                  }
                }
                return true
              }
              return true
            }else if(a === 'object'){
              let ak = Object.keys(a)
              let bk = Object.keys(b)
              if(ak.length !== bk.length){
                return false
              }else{
                for(let o in res1){
                  console.log(res1[o])
                  if(!isEqual(res1[o],res2[o])){
                    console.log('object',res1[o],res2[o])
                    return false
                  }
                }
                return true
              } 
            }else if(a === 'null' || a === 'undefined'){
              console.log('null')
              return true
            }else if(a === 'function'){
              console.log('function')
              return a === b
            }
          }
          
          function getTypeOf(res) {
            let type = Object.prototype.toString.call(res)
            switch (type) {
              case "[object Array]":
                return 'array'
              case "[object Object]":
                return 'object'
              case "[object Null]":
                return 'null'
              case "[object Undefined]":
                return 'undefined'
              case "[object Number]"||"[object String]"||"[object Boolean]":
                return 'base'
              case "[object Function]":
                return 'function'
              default:
                return 'typeError'
            }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          測(cè)試:
          let a = {
            a:20,
            b:{
              c:30,
              d:[1,2,3]
            }
          }
          let b = {
            a:20,
            b:{
              c:30,
              d:[1,2,3]
            }
          }
          console.log(isEqual(a,b)) //true 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16

          3.數(shù)組扁平化的方法

          function _flat(arr){
            let result = []
            for(let i = 0;i<arr.length;i++){
              if(Array.isArray(arr[i])){
                result = result.concat(_flat(arr[i]))
              }else{
                result.push(arr[i])
              }
            }
            return result;
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          let arr = [1,2,[3,4,[5,6]]]
          _flat(arr) //[1,2,3,4,5,6] 
          
          • 1
          • 2
          //es6
          function _flat2(arr){
            while(arr.some(item=>Array.isArray(item))){
              arr = [].concat(...arr)
            }
            return arr
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          let arr = [1,2,[3,4,[5,6]]]
          _flat2(arr) //[1,2,3,4,5,6] 
          
          • 1
          • 2

          4.深克隆

          簡(jiǎn)單深克隆,不考慮內(nèi)置對(duì)象和函數(shù)

          function deepClone(obj){
            if(typeof obj !== 'object') return
            let newObj = obj instanceof Array?[]:{}
            for(let key in obj){
                if(obj.hasOwnProperty(key)){
                    newObj[key] = typeof obj[key] === 'object'?deepClone(obj[key]):obj[key]
                }
            }
            return newObj
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10

          復(fù)雜版深度克隆 考慮內(nèi)置對(duì)象 比如date regexp 函數(shù) 以及對(duì)象的循環(huán)引用的問(wèn)題

          const isObject = (target) => typeof target === "object"&& target !== null;
          
          function deepClone2(target, map = new WeakMap()) {
            console.log(target)
              if (map.get(target)) {
                  return target;
              }
              // 獲取當(dāng)前值的構(gòu)造函數(shù):獲取它的類型
              let constructor = target.constructor;
              // 檢測(cè)當(dāng)前對(duì)象target是否與正則、日期格式對(duì)象匹配
              if (/^(RegExp|Date)$/i.test(constructor.name)) {
                  // 創(chuàng)建一個(gè)新的特殊對(duì)象(正則類/日期類)的實(shí)例
                  return new constructor(target);  
              }
              if (isObject(target)) {
                  map.set(target, true);  // 為循環(huán)引用的對(duì)象做標(biāo)記
                  const cloneTarget = Array.isArray(target) ? [] : {};
                  for (let prop in target) {
                      if (target.hasOwnProperty(prop)) {
                          cloneTarget[prop] = deepClone(target[prop], map);
                      }
                  }
                  return cloneTarget;
              } else {
                  return target;
              }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27

          5.數(shù)組去重

          filter去重

          function _unique(arr){
            return arr.filter((item,index,array)=>{
              return array.indexOf(item) === index
            })
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5

          es6 Set

          function _unique2(arr){
            return [...new Set(arr)]
          } 
          
          • 1
          • 2
          • 3

          includes

          function _unique3(arr){
            let newArr = []
            arr.forEach(item => {
                if(!newArr.includes(item)){
                  newArr.push(item)
                }
            });
            return newArr
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          雙層for循環(huán)

          function _unique4(arr){
            for(let i =0;i<arr.length;i++){
              for(let j =i+1;j<arr.length;j++){
                if(arr[i] === arr[j]){
                  arr.splice(j,1)
                  j--
                }
              }
            }
            return arr
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11

          indexof

          function _unique5(arr){
            let newArr = []
            for(let i = 0;i<arr.length;i++){
              if(newArr.indexOf(arr[i] === -1){
                newArr.push(arr[i])
              })
            }
            return newArr
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9

          6.判斷數(shù)據(jù)的類型

          function _typeOf(obj){
            let res = Object.prototype.toString.call(obj).split(' ')[1]
            let mold = res.substring(0,res.length-1).toLowerCase()
            return mold
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          _typeOf(5) //number
          _typeOf('5') //string 
          
          • 1
          • 2

          7.解析url參數(shù)為對(duì)象

          function getParamsObj(params){
            let paramsStr = params.replace(/^.+\?(.+)/,"$1")
            let paramsArr = paramsStr.split('&')
            let paramsObj = {}
          
            for(let [key,value] of paramsArr.entries()){
                if(/=/.test(value)){
                    let valArr = value.split('=')
                    val = decodeURIComponent(valArr[1]) //解碼
                    val = /^\d+$/.test(val)?parseFloat(val):val //判斷是不是數(shù)字
                    if(paramsObj.hasOwnProperty(valArr[0])){
                        paramsObj[valArr[0]] = [].concat(paramsObj[valArr[0]],val)
                    }else{
                        paramsObj[valArr[0]] = val
                    }
                }  
          
            }
            return paramsObj
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20

          8.函數(shù)柯里化

          //從一次傳入多個(gè)參數(shù)  編程多次調(diào)用每次傳入一個(gè)參數(shù)
          function add(a, b, c, d, e) {
            return a + b + c + d + e
          }
          
          function curry(fn) {
             let dFn = (...args)=>{
               if(args.length == fn.length) return fn(...args)
               return (...arg)=>{
                 return dFn(...args,...arg)
               }
             }
             return dFn
          }
          let addCurry = curry(add)
          addCurry(1,2,3)(2)(3) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17

          9.圖片懶加載

          //添加了兩個(gè)功能
          // 圖片加載完成后 移除事件監(jiān)聽(tīng)
          // 加載完的圖片從imgList中移除
          let imgList = [...document.querySelectorAll('img')]
          let length = imgList.length
          
          const imgLazyLoad = function () {
            let count = 0
            let deleteIndexList = []
            imgList.forEach((img, index) => {
              let rect = img.getBoundingClientRect() 
              //獲取元素到視圖的距離 top元素上邊到視圖上邊的距離 left元素左邊到視圖左邊的距離  right... bottom...
              if (rect.top < window.innerHeight) {
                // img.src = img.dataset.src
                img.src = img.getAttribute('data-src')
                deleteIndexList.push(index)
                count++
                if (count === length) {
                  document.removeEventListener('scroll', imgLazyLoad)
                }
              }
            })
            imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
          }
          imgLazyLoad()
          
          document.addEventListener('scroll', imgLazyLoad) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27

          圖片懶加載:https://juejin.cn/post/6844903856489365518#heading-19

          10節(jié)流防抖

          函數(shù)防抖 觸發(fā)高頻事件 事件在n后執(zhí)行,如果n秒鐘重復(fù)執(zhí)行了 則時(shí)間重置

          //簡(jiǎn)易版
          function debounce(func,wait){
            let timer; 
            return function(){
              let context = this;
              let args = arguments;
              console.log(timer)
              clearTimeout(timer)
              timer = setTimeout(function(){
                func.apply(context,args)
              },wait)
            }
          
          }
          let btn = document.querySelector('button');
          function aa(){
            console.log(111)
          }
          btn.onclick = debounce(aa,2000) 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          // 復(fù)雜版
          // 1.取消防抖  
          // 2.立即執(zhí)行功能(點(diǎn)擊之后立即執(zhí)行函數(shù)  但是 wait時(shí)間之后在點(diǎn)擊才能在立即執(zhí)行)  
          // 3.函數(shù)可能有返回值
          function debounce(func,wait,immediate){
            let timer,result;
          
            const debounce = function () {
              const context = this
              const args = arguments
          
              if(timer) clearTimeout(timer)
              if(immediate){
                console.log(timer)
                var callNow = !timer
                timer = setTimeout(function () {
                    timer =null
                },wait)
                if(callNow) result = func.apply(context,args)
              }else{
                timer = setTimeout(function (params) {
                  result = func.apply(context,args)
                },wait)
              }
              return result
            }
          
            debounce.cance = function () {
              clearTimeout(timer)
              timer=null
            }
          
            return debounce
          
          }
          
          let btn = document.querySelector('button');
          function aa(){
            console.log(111)
          }
          btn.onclick = debounce(aa,2000,true)``` 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41

          函數(shù)節(jié)流 觸發(fā)高頻事件 且n秒只執(zhí)行一次

          //使用時(shí)間戳
          function  throttle(func,wait) {
            var context,args;
            var previous = 0
          
            return function () {
              context = this;
              args = arguments;
              let nowDate = +new Date()
              if(nowDate-previous>wait){
                func.apply(context,arguments)
                previous = nowDate
              }
            }
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          //定時(shí)器
          function throttle(func,wait) {
            var context,args;
            var timer;
            return function(){
              context = this;
              args = arguments;
              if(!timer){
                timer = setTimeout(function () {
                  timer = null;
                  func.apply(context,args)
                },wait)
              }
            }
          
          } 
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          //組合版 options.leading 為true 立即執(zhí)行一次 options.trailing為true  結(jié)束之后執(zhí)行一次 默認(rèn)為true
          function throttle(func, wait ,options = {}) {
            var context, args, timer,result;
            var previous = 0;
          
            var later = function () {
              previous = options.leading === false ? 0 : new Date().getTime();
              timer = null;
              func.apply(context, args)
              if (!timer) context = args = null;
            }
          
            var throttle = function () {
              var now = new Date().getTime()
              if (!previous && options.leading === false) previous = now;
              context = this;
              args = arguments;
          
              //下次觸發(fā) func 剩余的時(shí)間
              var remaining = wait - (now - previous);
              if (remaining <= 0 || remaining > wait) {
                // if (timer) {
                //   clearTimeout(timer);
                //   timer = null;
                // }
                previous = now;
                func.apply(context, args);
                if (!timer) context = args = null;
              } else if (!timer&& options.trailing !== false) {
                timer = setTimeout(later, remaining);
              }
            }
          
            throttled.cancel = function() {
              clearTimeout(timer);
              previous = 0;
              timer = null;
            }
          
            return throttle
          }
          
          function aa(e) {
            console.log(111)
            console.log(e)
          }
          
          let btn = document.querySelector('button');
          btn.onclick = throttle(aa, 2000,{
            leading:false,
            trailing:true 
          

          })

          轉(zhuǎn)自:csdn論壇 作者:Selfimpr歐

          日歷

          鏈接

          個(gè)人資料

          存檔

          久久精品国产2020| 久久影视综合亚洲| 亚洲中文精品久久久久久不卡| 国产精品亚洲综合久久| 久久久久av无码免费网| 久久久久国产精品三级网| 久久国产精品免费| 婷婷久久精品国产| 97久久国产露脸精品国产 | 亚洲国产精品无码久久久不卡| 亚洲午夜久久久影院伊人| 亚洲色欲久久久久综合网| 色狠狠久久AV五月综合| 中文字幕一区二区三区久久网站| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久亚洲精品成人av无码网站| 久久天天躁夜夜躁狠狠| 久久精品极品盛宴观看| 精品熟女少妇av免费久久| 青青草原综合久久大伊人精品| 久久久久成人精品无码| 国产精品欧美久久久久天天影视| 91精品免费久久久久久久久| Xx性欧美肥妇精品久久久久久| 国内精品久久久久国产盗摄| 久久国产视屏| 欧美久久一区二区三区| 久久精品成人欧美大片| 久久综合给合久久狠狠狠97色| 国内精品久久久久久久97牛牛 | 久久99亚洲综合精品首页| 久久亚洲精品无码观看不卡| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 久久精品日日躁夜夜躁欧美| 久久久久久九九99精品| 中文字幕久久精品 | 久久精品www| 色欲综合久久躁天天躁蜜桃| 国产精品久久久久久久久免费| 97香蕉久久夜色精品国产 | 久久99国产精品一区二区|