【手写之JS基础】1) 实现防抖函数

一、原理:

  • 防抖函数用于确保在某个连续触发的事件结束后,监听该事件的回调函数在事件无触发n秒之后才执行一次

    在这里插入图片描述

  • 这对于处理用户输入、窗口大小调整等频繁触发的事件很有用

  • 可见,debounce函数控制回调函数执行的频率,那么debounce函数的返回值应该是一个函数。
    参数有两个1.获取到的回调函数 2. 设置的规定时间

二、代码实现

function debounce(callback,delay){
  let timerId = null; // 用于保存定时器的ID

  function _debounce(...args){
    if(timerId) clearTimeout(timerId)  // 取消上一个定时器
    // 等待delay后,将监听事件的回调函数放入宏任务队列中
    timerId = setTimeout(()=>{
      callback.apply(this,args);
    },delay)
  }

  return _debounce;
}

// 用防抖函数debounce将原先绑定给事件的函数包裹一下,这样的话,就能实现图中的功能了
const debounceFn = debounce(fn,2000)
debounceFn("hello",123)

1. 解决回调函数的this指向问题

当你使用DOM事件监听器时,事件回调函数内的this默认指向触发事件的 DOM 元素。这是因为事件处理函数会在元素上下文中执行

  • 回调函数是箭头函数形式: 指向外部的作用域的this
  • 回调函数是普通函数形式: 内部的 this 不会指向触发事件的DOM 元素
<body>
  <button class="btn"></div>
</body>
<script>
   const btn = document.querySelector(".btn")
   // btn.addEventListener("click",()=>{})
   btn.addEventListener("click",fn)
  }
</script>

解决方法:

调用debounce函数最终返回_debounce函数,相当于监听事件的回调函数是_debounce,因此_debounce函数的this一定指向DOM元素,因此我们在_debounce函数内执行callback时,使得callback的this与_debounce函数一样即可(否则callback的this指向就会根据执行环境而变化)

  • 要么将定时器内部的函数,写成箭头函数形式
function debounce(func,delay){
  var timer = null;
  
  function _debounce(){
    if(timer) clearTimeout(timer);
    timer = setTimeout(()=>{
      func.apply(this)
      /* 
        箭头函数内部的this在定义时就确定了,与外部非箭头函数的this指向一致
        这里的外部非箭头函数 === _debounce函数
     */
    },delay)
  }

  return _debounce;
}
  • 要么将定时器内部的函数,写成普通函数,但是用变量_this保存_debounce函数的this指向
function debounce(func,delay){
  var timer = null;
  function _debounce(){
    var _this = this;   // 用 _this 记录当前的this
    
    clearTimeout(timer);
    timer = setTimeout(function(){
      func.apply(_this);
    },delay)
  }

  return _debounce;
}

2. 解决参数问题

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值