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

目录

参数问题
现象
结论
箭头函数
试验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) } }

控制台会输出:

分析

从两个试验可以看出,箭头函数会把内部的 thisarguments 绑定为与定义时的上层一致。

而上一层就是我们的事件监听器直接调用的函数,所以这时候的 argumentsthis 都是正确的。

知识点

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

本文作者:mereith

本文链接:

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