javascript 深度克隆与防抖节流

原文博客链接

藤原拓鞋的博客

深度拷贝

/**拷贝数据
 * 基本数据类型拷贝:
 *     拷贝后会生成一份新的数据,修改拷贝以后的数据,不会影响原来数据
 * 对象/数组:
 *     拷贝后不会生成新的数据,而是拷贝对数据的引用,修改拷贝以后的数据,会影响原来数据
 *
 * 拷贝数据的方法:
 *    1. 直接赋值给一个变量 =    //浅拷贝
 *    2. Object.assign(target,obj1,obj2)        //浅拷贝
 *    3. Array.prototype.concat(arr1,arr2)   //浅拷贝
 *    4. Array.prototype.slice(startIndex,endIndex)   //浅拷贝
 *    5. JSON.parse(JSON.stringify())    //深拷贝
 * 浅拷贝(对象/数组):
 *    拷贝的引用,修改拷贝以后的数据,会影响原数据
 * 深拷贝(对象/数组):
 *    拷贝以后生成新的数据
 */

//实现深度拷贝
//先定义检测数据类型的功能函数
function checkType(target) {
  //Object.prototype.toString()方法生成[Object Array],[Object Object] 这样的数据,是最好的判断类型的方法,再通过slice(),获取有效部分
  return Object.prototype.toString.call(target).slice(8, -1);
}

//实现深度克隆(对象/数组)
function clone(target) {
  //判断拷贝的数据类型
  //初始化变量result,成为最终的克隆数据
  let result;
  let targetType = checkType(target);
  if (targetType === "Object") {
    //需要拷贝的数据是对象,先让result为一个空对象
    result = {};
  } else if (targetType === "Array") {
    //需要拷贝的数据是数组,先让result为一个空数组
    result = [];
  } else {
    //需要拷贝的数据是基本数据类型,直接返回原数据
    return target;
  }

  //遍历目标数组或对象
  for (let i in target) {
    //for...in 语句以原始插入顺序迭代对象的可枚举属性(考虑原型链),for...of 语句遍历可迭代对象定义要迭代的数据
    //for(let i in target) 返回的是对象的键名,数组的下标
    //遍历数据结构的每一项值
    let value = target[i];
    //判断目标结构的每一项值是否存在对象/数组
    if (checkType(value) === "Object" || checkType(value) === "Array") {
      //   对象/数组 里嵌套了 对象/数组 ,需要递归clone(value)
      //继续遍历获取到的value值
      result[i] = clone(value);
    } else {
      //  获取到的value值是基本数据类型或者函数,直接赋值
      result[i] = value;
    }
  }

  return result;
}

export default clone;

节流与防抖

// 节流与防抖

// 所谓防抖,是指触发事件后在n秒内函数只能执行一次,
// 如果在n秒内又触发了事件,则会重新计算函数执行时间
function debounce(func, wait) {
  let timeout;
  return function () {
    let context = this;
    let args = arguments;

    if (timeout) {
      // 如果timeout有值,即前面已经设置了定时器,则清除定时器,重新设置
      clearTimeout(timeout);
    }

    timeout = setTimeout(() => {
      func.apply(context, args);
    }, wait);
  };
}

// 所谓节流,就是指连续触发事件但是在n秒内只执行一次函数,节流会稀释函数的执行频率
function throttle(func, wait) {
  let timeout;
  return function () {
    let context = this;
    let args = arguments;

    if (!timeout) {
      // 如果timeout没有值,则设置定时器。 如果前面已经设置了定时器,timeout有值,则不做操作。 如果前面设置的定时器执行了,timeout设置了null,则重新设置定时器
      timeout = setTimeout(() => {
        timeout = null;
        func.apply(context, args);
      }, wait);
    }
  };
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值