一些常见的手撕算法:深拷贝、防抖、节流

75 阅读1分钟

深拷贝

定义:深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。即:修改其中一个变量,另一个不受影响。

一眼大开门(考虑循环引用的问题)

function deepClone(obj, map = new Map()){
  if(typeof obj !=="object" || obj === null)
    return obj
  let result = Array.isArray(obj)? [] : {}
  map.set(obj, result)
  for (const key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) {
      const element = obj[key];
      if(map.has(element)){
        result[key] = map.get(element)
        continue
      }
      if(typeof element ==="object" && element !== null){
        result[key] = deepClone(element, map)
      }else{
        result[key] = element
      }
      map.set(element, result[key])
    }
  }
  return result
}
let obj = {
  a: '132',
  b: [1,2,3,4],
}
// 测试循环引用
obj.d = obj.b
obj.c = obj
let objCopy = deepClone(obj)
// 测试深拷贝
objCopy.a = '333'
objCopy.b[0] = 10
console.log(obj, objCopy);

执行效果如下图(带有循环引用的对象可以正常拷贝)

image.png

防抖

定义:是指在一定时间内,在动作被连续频繁触发的情况下,动作只会被执行一次,也就是说当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

一眼大开门(绑定this与arguements)

// 防抖函数
function debounce(func,delay) {
    let timer;
    return function() {
    	let context = this;
        if(timer) clearTimeout(timer) // 每次执行的时候把前一个 setTimeout clear 掉
        timer = setTimeout(()=> {
            func.apply(context,arguments)
        },delay)
    }
}

节流

定义:所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数

一眼大开门(绑定this与arguements)

function throttle(func, wait) {
    // 定时器版
    let timer;
    return function () {
        let context = this;
        if (!timer) {
            timer = setTimeout(() => {
                timer = null;
                func.apply(context, arguments)
            }, wait)
        }
    }
}