背八股文的时候温习了一下防抖和节流的概念。于是自己随手把网上的版本试了一下,发现不行:
<body> <button id="debounce">防抖测试</button> <script> function debounce(fn, delay) { let timer = null; return function () { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this) }, delay) } } document.querySelector("#debounce").addEventListener("click", debounce((ev) => { console.log(ev) }, 500)) </script> </body>
控制台会打印 undefined。
setTimeout 里我们的函数执行的时候,没有参数。所以应该改为:
timer = setTimeout(() => { fn.apply(this,arguments) }, delay)
所以里面的 apply 可以通俗的理解为就是为了传参数进去用的。
但为什么这样就可以呢?为啥arguments 就对了呢?
setTimeout 里面用的是箭头函数,那我们用普通函数会发生什么?
timer = setTimeout(function () { fn.apply(this,arguments) }, delay)
控制台会打印:
undefined
我们修改一下代码:
function debounce(fn, delay) { let timer = null; return function () { console.log(this,arguments); setTimeout(function () { console.log(this,arguments); },delay) setTimeout(()=>{ console.log(this,arguments); },delay) } }
控制台会输出:

从两个试验可以看出,箭头函数会把内部的 this 和 arguments 绑定为与定义时的上层一致。
而上一层就是我们的事件监听器直接调用的函数,所以这时候的 arguments 和 this 都是正确的。
this 指向 window。如果是事件监听,就是触发事件的对象。this 就会指向该对象。this 指向返回的这个对象。this 绑定看的是 this 所在函数定义在哪个对象下,就绑定哪个对象。如果有嵌套的情况,则 this 绑定到最近的一层对象上。Function.prototype 上的 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply 接收参数的是数组,call 接受参数列表,bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。若为空默认是指向全局对象 window。背八股文的时候温习了一下防抖和节流的概念。于是自己随手把网上的版本试了一下,发现不行:
<body> <button id="debounce">防抖测试</button> <script> function debounce(fn, delay) { let timer = null; return function () { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this) }, delay) } } document.querySelector("#debounce").addEventListener("click", debounce((ev) => { console.log(ev) }, 500)) </script> </body>
控制台会打印 undefined。
setTimeout 里我们的函数执行的时候,没有参数。所以应该改为:
timer = setTimeout(() => { fn.apply(this,arguments) }, delay)
所以里面的 apply 可以通俗的理解为就是为了传参数进去用的。
但为什么这样就可以呢?为啥arguments 就对了呢?
setTimeout 里面用的是箭头函数,那我们用普通函数会发生什么?
timer = setTimeout(function () { fn.apply(this,arguments) }, delay)
控制台会打印:
undefined
我们修改一下代码:
function debounce(fn, delay) { let timer = null; return function () { console.log(this,arguments); setTimeout(function () { console.log(this,arguments); },delay) setTimeout(()=>{ console.log(this,arguments); },delay) } }
控制台会输出:

从两个试验可以看出,箭头函数会把内部的 this 和 arguments 绑定为与定义时的上层一致。
而上一层就是我们的事件监听器直接调用的函数,所以这时候的 arguments 和 this 都是正确的。
this 指向 window。如果是事件监听,就是触发事件的对象。this 就会指向该对象。this 指向返回的这个对象。this 绑定看的是 this 所在函数定义在哪个对象下,就绑定哪个对象。如果有嵌套的情况,则 this 绑定到最近的一层对象上。Function.prototype 上的 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply 接收参数的是数组,call 接受参数列表,bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。若为空默认是指向全局对象 window。