JS 工具函数

109 阅读3分钟

常见工具函数

防抖函数

  • 利用防抖函数,控制执行函数的触发次数,只提交最后一次(可设置首次提交)
  • 设定间隔时间内只执行一次,如果频繁触发事件,那么让任务每次都重新计时
  • 优化:利用柯里化函数思想
function debouncePlus(fn, delay = 500, immediate = true) {
  if(typeof fn !== 'function') {
    throw new TypeError('fn 不是一个函数')
  }
  
  if(typeof immediate !== 'boolean') {
   immeaiate = true;
  }
  
  let t = null; // 定时器
  
  return function() {
   let _self = this, // 保存this 是为了事件函数fn不丢失this
       args = arguments,
       now = immediate && !t; // 首次执行的标记
       
       clearTimeout(t); // 清理上一次的定时器
       
       t = setTimeout(() => {
           t = null;
           !now ? fn.apply(_self, args) : null
       }, delay)
       
       
     // 如果immediate为true且 定时器为空, 保证先执行一次
     now ? fn.apply(_self, args) : null
  }
}

节流函数

  • 控制事件触发的频率
  • 设定指定时间内无论如何执行一次,如果频繁触发事件,不作回应,必须等待间隔时间
 function throttlePlus(fn, time) {
   if(typeof fn !== 'function') {
     throw new TypeError('fn 不是一个函数')
   }
   
   let t = null,
       begin = now Date().getTime(); // 记录一个起始时间
       
   return function() {
    let _self = this,
        args = arguments,
        curr = new Date().getTime(); // 记录当前时间
        
        clearTimeout(t)
        
        if(curr - begin >= time) {
         fn.call(_self,...args); // 不使用apply args旧的解构一下
         begin = curr; // 重置起始时间
         }else {
          t = setTimeout(() => {
           fn.call(_self, ...args)
          }, time);
         }
   }
 }

ES6深拷贝

  • 只针对数组或对象进行深拷贝,不考虑其它问题如:Date 对象,RegExp对象
function deepClone(origin) {
 if(origin === 'undefined' || typeof origin !== 'object') {
    return origin;
 }
 
 // 原型上的 constructor指向 对象本身的构造类型,可以替代toString 进行类型判断再返回 [] || {}
 let target = new origin.constructor();
 
 for(let k in origin) {
   if(Object.hasOwn(origin, k)) {
      // 递归-添加键值对,如果是原始类型 入口处的if判断会将其返回
      target[k] = deepClone(origin[k])
   }
 }
 return target;
}

封装 typeof

  • typeof 无法准确识别 null ,Array
  • instanceof 检测的是原型之间的关联性,无法准确识别 Function,Array, 原因:函数 || 数组也是特殊的对象
  • 一般 对象原型方法 toString() 可以满足日常开发了
  • 注释:typeof 检测类型 返回一个小写字符串如 string, toString() 检测类型 返回一个数组字符串如 '[object Array]'
 function typeOfPlus(val) {
  let type = typeof val,
      toStr = Object.prototype.toString;
   let res = {
        '[object Array]': 'array',
        '[object Object]': 'object',
        '[object Number]': 'object number',
        '[object String]': 'object string',
        '[object Boolean]': 'object boolean',
        '[object RegExp]': 'object RegExp',
        '[object Date]': 'object Date'
    }
    
    if(val === null) {
       return 'null'
    }else if(type === 'object') {
      // 如果typeof 检测结果=== ‘object’ 重新检测
      let ret = toStr.call(val)
      return res[ret]; // 返回映射类型
    } else {
      return type; // 如果不属于以上情况 那么正常返回typeof 检测的结果即可
    }
 }

数组去重

let arr = [2, 4, 5, 56, 6, 56, 5, 6, 'int', 'Gen', 'int']

function removeRepetition(arr) {
    return arr.filter((item, index) => {
        return arr.indexOf(item) === index;
            // item -> 2    indexOf返回索引位 -> 0  === index 0  true
            // item -> 4    indexOf返回索引位 -> 1  === index 1  true
            // item -> 5    indexOf返回索引位 -> 2  === index 2  true
            // item -> 56   indexOf返回索引位 -> 3  === index 3  true
            // item -> 6    indexOf返回索引位 -> 4  === index 4  true
            // item -> 56   indexOf返回索引位 -> 5  === index 3  false -> 重复:不返回值
            // item -> 5    indexOf返回索引位 -> 6  === index 2  false -> 重复:不返回值
            // item -> 6    indexOf返回索引位 -> 7  === index 4  false -> 重复:不返回值
            // item -> int  indexOf返回索引位 -> 8  === index 8  true
            // item -> Gen  indexOf返回索引位 -> 9  === index 9  true
            // item -> int  indexOf返回索引位 -> 10 === index 8  false -> 重复:不返回值
    })
}