我有一个具有一个属性和一个方法的对象。该方法包含一个带有默认参数的递归 IIFE,它应该在每次调用时延迟更新 objects 属性。为了确保它正确执行,我使用 bind(this) 将 IIFE 绑定(bind)到属性和索引(用作计数器)。但我不确定我的代码中的 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 设置为 [0],在 3 秒 [1]、3 秒 [2]、3 秒 [3] 之后,然后重复自身 ([0],...)。
但我的问题是关于为什么它以这种方式工作,更具体地说,bind(this) 在这里做了什么以使其按照它的方式工作。
1) 首先在 setTimeout 中绑定(bind)(this): 正如我在这里理解的那样,bind(this) 创建了一个包装 IIFE 的新函数,并将 IIFE 的上下文传递给这个新函数。由于上下文包含 myObj 的范围,因此在调用 IIFE 时始终将其设置为 myObj 的范围。
2) 第二个绑定(bind)(this): 我真的不确定为什么它确保每次调用 IIFE 时都传递正确的索引 ...
如果有人能详细解释到底发生了什么以及为什么它以这种方式工作,那就太好了。非常感谢您。
最佳答案
这一切都涉及 .bind()
调用的原因是,如果没有它,对 recIIFE()
函数的调用将不会有 this
设置为 myObj
。
对“递归”函数的初始调用(它不是真正的递归,但我现在先放一放)是注释中标记为“第二”的函数。外部 .bind(this)()
创建函数的第一个绑定(bind)版本,它绑定(bind) myMethod()
中 this
的值>,即外部对象 myObj
。
现在,在第一次调用 recIIFE()
时,没有传递任何参数,因此使用默认值 0。这会将 myArr
设置为 [0]
。
接下来是 setTimeout()
调用。在 recIIFE()
内部,函数名称(“recIIFE”)仍然引用预绑定(bind) 函数;换句话说,不是从 myMethod()
创建并立即调用的函数,而是原始函数。因此,它必须再次绑定(bind)才能使计时器调用正常工作。 this
的值仍然是 myObj
,所以这很简单。
最后,关于如何调用 setTimeout()
的决定只是检查索引与值数组长度的比较,以便它在耗尽所有其余元素后从第一个元素开始。
recIIFE()
不是真正递归的原因是在任何给定时间只有一个函数激活运行。从来没有一堆调用中的调用。除非您非常关心术语,否则这并不是什么大问题。
关于javascript - bind(this) inside recursive IIFE - 它到底在做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57842141/