我有一个具有一种属性和一种方法的对象。该方法包含具有默认参数的递归IIFE,该IIFE每次调用对象属性时都应在一定程度上延迟更新。为了确保它正确执行,我将IIFE绑定到具有bind(this)的属性和索引(用作计数器)。但是我不确定我代码中的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中绑定(this): 据我了解,bind(this)创建了一个包装IIFE的新功能,并将IIFE的上下文传递给此新功能。由于上下文包括myObj的范围,因此在调用IIFE时始终将其设置为myObj的范围。
2)第二个绑定(this): 我真的不确定为什么要确保每次调用IIFE都传递正确的索引...
如果有人可以详细解释到底发生了什么以及为什么它以这种方式起作用,那将是很棒的。预先非常感谢。
答案 0 :(得分:1)
这全部涉及.bind()
调用的原因是,如果不这样做,则对该recIIFE()
函数的调用不会将this
设置为myObj
。
最初对“递归”函数的调用(它不是真正的递归,但现在让我放这张幻灯片)是在注释中标记为“第二”的那个。外部.bind(this)()
创建函数的第一个绑定版本,并绑定this
中myMethod()
的值,即外部对象myObj
。
现在,在第一次调用recIIFE()
时,没有传递任何参数,因此使用默认值0。将myArr
设置为[0]
。
下一个setTimeout()
呼叫。在recIIFE()
内部,函数名称(“ recIIFE”)仍指预绑定函数;换句话说,不是 函数,而是最初从myMethod()
创建并立即调用的函数。因此,必须重新绑定定时器调用才能正常工作。 this
的值仍然是myObj
,所以很简单。
最后,关于如何调用setTimeout()
的决定仅是检查与值数组长度相比的索引,以便索引在耗尽所有其余部分之后从第一个元素开始。
recIIFE()
并非真正递归的原因是,在任何给定时间,只有一次激活的功能正在运行。通话中从来没有一堆电话。除非您非常关心术语,否则这并不是真正的问题。