常见手写

105 阅读1分钟

手写深拷贝

export function deepClone(obj, hash = new WeakMap()) {
  // 处理null或者undefined
  if (obj === null) return obj;
  // 处理日期类型
  if (obj instanceof Date) return new Date(obj);
  // 处理正则类型
  if (obj instanceof RegExp) return new RegExp(obj);
  // 普通值或函数不需要深拷贝
  if (typeof obj !== "object") return obj;
  // 对象进行深拷贝
  if (hash.get(obj)) return hash.get(obj);
  let cloneObj = new obj.constructor();
  // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
  hash.set(obj, cloneObj);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      // 实现一个递归拷贝
      cloneObj[key] = deepClone(obj[key], hash);
    }
  }
  return cloneObj;
}

手写new

  function myNew (fun,...args){
      if(typeof fun !== 'function') {
          throw Error('只能是函数')
      }

    //   定义返回去的对象
    const obj = {}
    obj.__proto__ = Object.create(fun.prototype)

    // 执行构造函数
    const res = fun.call(obj,...args)
    
    //  如果返回的结果是对象就返回这个对象
     if(typeof res === 'object') return res
    return obj
  }

手写防抖

function debounce(fun,delay){
    let timer = ''
    return function(){
        if(timer){
            // 如果已经设置了,就清楚定时器
            clearTimeout(timer)
        }
        // 设置延时器
        timer = setTimeout(()=>{
            // 调用真正要执行的函数
            fun.apply(this,arguments)
            timer = null
        },delay)
    }
}

手写节流 定时器版本

function throttle(fn,interval){
    let timer = ''
    return function () {
        if(timer){
            //如果存在 就return  不重复执行
            return
        }
        timer = setTimeout(()=>{
            fn.apply(this,arguments)
            clearTimeout(timer)
            timer = null
        },interval)
    }

}

手写call

Function.prototype.myCall = function(context,args){
  const context = context || window
  // 生成唯一的属性
  const key = Symbol('key')

  context[key] = this
  
  // 执行函数
  const res = context[key](args)

  delete context[key]
  return  res
}

数组转树 非递归方式

function arrToTree(data) {
  const result = []
  //父ID集合 用来找children
  const map = data.reduce((pre, cur) => {
    pre[cur[id]] = {
      ...cur,
      children: []
    }
    return pre
  }, {})

  for (const item of data) {
    const newItem = map[item.id]
    // 如果在父集合里 说明该项是父集合中的children
    if (map[item.pId]) {
      map[item.pId].children.push(newItem)
    } else {
      result.push(newItem)
    }
  }

  return result
}

扁平化树 reduce 加递归实现

const tree = [
    {
        id:1,
        label:1,
        children:[{
            id:11,
            label:11
        },{
            id:12,
            label:12
        }]
    }
]
function flat(tree){
  return tree.reduce((v,c)=>{
          const {children,...item} = c
         return children?.length ? v.concat(item,flat(children)) : v.concat(item)
    }, [])
}