• <center id="sm46c"></center>
  • <dfn id="sm46c"></dfn>
  • <strike id="sm46c"></strike>
  • <cite id="sm46c"><source id="sm46c"></source></cite>
    • <strike id="sm46c"><source id="sm46c"></source></strike>
      <option id="sm46c"></option>
      国产精品天天看天天狠,女高中生强奷系列在线播放,久久无码免费的a毛片大全,国产日韩综合av在线,亚洲国产中文综合专区在,特殊重囗味sm在线观看无码,中文字幕一区二区三区四区在线,无码任你躁久久久久久老妇蜜桃

      死磕javascript的手寫面試題

      2021-4-15    前端達人

      1.實現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
      測試:
      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.寫一個函數判斷兩個變量是否相等

      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{
            //遍歷數組的值比較
            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
      測試:
      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.數組扁平化的方法

      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.深克隆

      簡單深克隆,不考慮內置對象和函數

      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

      復雜版深度克隆 考慮內置對象 比如date regexp 函數 以及對象的循環引用的問題

      const isObject = (target) => typeof target === "object"&& target !== null;
      
      function deepClone2(target, map = new WeakMap()) {
        console.log(target)
          if (map.get(target)) {
              return target;
          }
          // 獲取當前值的構造函數:獲取它的類型
          let constructor = target.constructor;
          // 檢測當前對象target是否與正則、日期格式對象匹配
          if (/^(RegExp|Date)$/i.test(constructor.name)) {
              // 創建一個新的特殊對象(正則類/日期類)的實例
              return new constructor(target);  
          }
          if (isObject(target)) {
              map.set(target, true);  // 為循環引用的對象做標記
              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.數組去重

      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循環

      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.判斷數據的類型

      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參數為對象

      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 //判斷是不是數字
                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.函數柯里化

      //從一次傳入多個參數  編程多次調用每次傳入一個參數
      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.圖片懶加載

      //添加了兩個功能
      // 圖片加載完成后 移除事件監聽
      // 加載完的圖片從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節流防抖

      函數防抖 觸發高頻事件 事件在n后執行,如果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
      // 復雜版
      // 1.取消防抖  
      // 2.立即執行功能(點擊之后立即執行函數  但是 wait時間之后在點擊才能在立即執行)  
      // 3.函數可能有返回值
      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

      函數節流 觸發高頻事件 且n秒只執行一次

      //使用時間戳
      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
      //定時器
      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 立即執行一次 options.trailing為true  結束之后執行一次 默認為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;
      
          //下次觸發 func 剩余的時間
          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 
      

      })

      轉自:csdn論壇 作者:Selfimpr歐

      日歷

      鏈接

      個人資料

      藍藍設計的小編 http://www.li-bodun.cn

      存檔

      主站蜘蛛池模板: 亚洲成av人片天堂网九九| 高大丰满欧美熟妇hd| 久久蜜臀av一区三区| 天天澡天天添天天摸97影院| 久久99国产精品成人| 人妻视频一区二区三区免费| 黄色不卡视频一区二区三区| 97人妻中文字幕总站| 亚洲色大成网站www看下面| 成年奭片免费观看视频天天看| 无码人妻精品一区二区三区下载 | 柘城县| 欧美交A欧美精品喷水| 亚洲精品在线视频自拍| 三门峡市| 日韩精品亚洲专区在线播放| 亚洲精品一区二区妖精| 精品无码国产一区二区三区av| 亚洲爆乳WWW无码专区| 四虎影视国产精品永久在线| 久久精品国产国产精品四凭| 天堂网www在线资源| 久久国产精品久久喷水| 大邑县| 欧美丰满熟妇bbbbbb百度| av深夜福利在线| 国产精品制服一区二区| 人妻 校园 激情 另类| 亚洲国产精品成人综合色在| 亚洲阿v天堂网2021| 亚洲人成网站观看在线观看| 国产福利99| 无码av最新高清无码专区| 国内精品一区二区三区| 波多野结衣国产精品| 激情综合五月| 亚洲三级网站| 国偷自产一区二区三区在线视频| 人人妻人人超人人| 8AV国产精品爽爽ⅤA在线观看| 无码精品人妻一区二区三区影院|