手写防抖和节流

104 阅读1分钟

防抖

举🌰:

鼠标移动时,随时计算鼠标所在的位置,但是为了较少计算量,只在鼠标停下1s后才调用函数计算鼠标位置。

王者荣耀:在回城的时候,如果被打断了,就要重新来


function debounce(fn, delay = 200) {
  let timer = 0 return function () { 
    if (timer) { clearTimeout(timer) }
    timer = setTimeout(() => {
      fn.apply(this, arguments);
      timer = 0
    }, delay)
  }
}


addBtn.addEventListener('click',debounce(addOne,1000))

节流

王者荣耀:放大招之后,只有一段时间结束后,才能再次放大招。


function throttle(fn, delay = 200) {
  let timer = 0
  return function () {
    if (timer) {
      return
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments) // 透传 this和参数
      timer = 0
    }, delay)
  }
}

 

疑问:

为什么要绑定thisconst obj = {
  name:'jack',
  addOne(e){
    console.log(e.target)
  }
}

addBtn.addEventListener('click',throttle(obj.addOne,1000))

假设我们是通过obj.addOne的方式调用fn函数的,如果执行`fn(...args)`

那函数的执行就是在对象obj的上下文中被调用的。

但是!

我们在执行throttle(obj.addOne,1000)的时候,明显是在借用obj上的这个函数内容,并没有想让函数在obj上执行。

我们在上述示例中,实际上想让函数fn在全局环境下被调用。

所以!要调整this的指向。