编辑
2022-07-26
前端技术
00
请注意,本文编写于 1545 天前,最后修改于 1540 天前,其中某些信息可能已经过时。

目录

参数问题
现象
结论
箭头函数
试验1
试验2
分析
知识点

参数问题

现象

背八股文的时候温习了一下防抖和节流的概念。于是自己随手把网上的版本试了一下,发现不行:

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 里我们的函数执行的时候,没有参数。所以应该改为:

js
timer = setTimeout(() => { fn.apply(this,arguments) }, delay)

所以里面的 apply 可以通俗的理解为就是为了传参数进去用的。

但为什么这样就可以呢?为啥arguments 就对了呢?

箭头函数

试验1

setTimeout 里面用的是箭头函数,那我们用普通函数会发生什么?

js
timer = setTimeout(function () { fn.apply(this,arguments) }, delay)

控制台会打印:

undefined

试验2

我们修改一下代码:

js
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 都是正确的。

知识点

  1. 作为普通函数执行时,this 指向 window。如果是事件监听,就是触发事件的对象。
  2. 当函数作为对象的方法被调用时,this 就会指向该对象。
  3. 构造器调用,this 指向返回的这个对象。
  4. 箭头函数的 this 绑定看的是 this 所在函数定义在哪个对象下,就绑定哪个对象。如果有嵌套的情况,则 this 绑定到最近的一层对象上。
  5. 基于 Function.prototype 上的 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。apply 接收参数的是数组,call 接受参数列表,bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。若为空默认是指向全局对象 window。
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:mereith

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!