javascript - 递归 IIFE 中的 bind(this) - 它到底在做什么?
问题描述
我有一个具有一个属性和一个方法的对象。该方法包含一个带有默认参数的递归 IIFE,每次调用它时都会延迟更新 objects 属性。为了确保它正确执行,我使用 bind(this) 将 IIFE 绑定到属性和索引(用作计数器)。但我不确定我的代码中的 bind(this) 实际上在做什么......
myObj = {
myArr: [],
myMethod: function (myData = [0,1,2,3]) {
(function recIIFE(index = 0) {
console.log(index);
this.myArr[0] = myData[index];
console.log(this.myArr);
index < myData.length - 1
? setTimeout(recIIFE.bind(this), 3000, index += 1) // First bind(this)
: setTimeout(recIIFE.bind(this), 3000, index = 0);
}).bind(this)(); // Second bind(this)
}
}
myObj.myMethod();
所以输出是,myArr 在 3sec [1]、3secs [2]、3secs [3] 之后设置为 [0],然后重复自身([0],...)。
但是我的问题涉及为什么它以这种方式工作,更具体地说, bind(this) 在这里做了什么以使其以它的方式工作。
1)在setTimeout中首先绑定(this):据我所知,bind(this)创建一个包装IIFE的新函数并将IIFE的上下文传递给这个新函数。由于上下文包括 myObj 的范围,因此当调用 IIFE 时,它始终设置为 myObj 的范围。
2)第二次绑定(this):我真的不确定为什么每次调用 IIFE 时都会确保传递正确的索引......
如果有人能详细解释到底发生了什么以及为什么它会以这种方式工作,那就太好了。非常感谢您提前。
解决方案
这一切都涉及.bind()
调用的原因是,如果没有它,对该recIIFE()
函数的调用将不会this
设置为myObj
.
对“递归”函数的初始调用(它不是真正的递归,但我现在先放一张幻灯片)是注释中标记为“第二”的那个。该外部.bind(this)()
创建了该函数的第一个绑定版本,它绑定了this
in的值myMethod()
,即外部对象myObj
。
现在,在第一次调用中recIIFE()
,没有传递任何参数,因此使用默认值 0。设置myArr
为[0]
。
接下来setTimeout()
是电话。里面recIIFE()
,函数名(“recIIFE”)仍然指的是预绑定的函数;换句话说,不是从 中创建并立即调用的函数myMethod()
,而是原始函数。因此,它必须再次绑定,定时器调用才能正常工作。的值this
仍然是myObj
,所以这很简单。
最后,关于如何调用的决定setTimeout()
只是检查索引与值数组长度的比较,以便在耗尽所有其余元素后从第一个元素重新开始。
不是真正递归的原因recIIFE()
是在任何给定时间只有一个激活函数正在运行。从来没有一堆调用中的调用。除非您非常关心术语,否则这并不是什么大问题。
推荐阅读
- regex - 如何使用正则表达式匹配包含/排除某些字符串的多行文本?
- php - WooCommerce 中每种运输方式的设置存储在哪里?
- laravel - 我如何在 Laravel 中使用 belongsTo
- angular6 - 为什么默认检查属性在 Angular 6 中不起作用
- c# - 加载资源失败
- python - 是否可以在 PyCharm 中拆分输出控制台?
- xcode - 我应该使用什么约束?
- database - WP_User_Query 在庞大的数据库上花费时间进行分页
- git - git-svn 不适用于 Ubuntu 18.04.1 LTS
- qt - 使用 Qt WebGL 进行屏幕共享(如 VNC)