背八股文的时候温习了一下防抖和节流的概念。于是自己随手把网上的版本试了一下,发现不行:
html<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
里我们的函数执行的时候,没有参数。所以应该改为:
jstimer = setTimeout(() => { fn.apply(this,arguments) }, delay)
所以里面的 apply
可以通俗的理解为就是为了传参数进去用的。
但为什么这样就可以呢?为啥arguments
就对了呢?
setTimeout
里面用的是箭头函数,那我们用普通函数会发生什么?
jstimer = setTimeout(function () { fn.apply(this,arguments) }, delay)
控制台会打印:
undefined
我们修改一下代码:
jsfunction 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
。本文作者:mereith
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!