首页 > 解决方案 > 递归 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 时都会确保传递正确的索引......

如果有人能详细解释到底发生了什么以及为什么它会以这种方式工作,那就太好了。非常感谢您提前。

标签: javascriptrecursionthisbindiife

解决方案


这一切都涉及.bind()调用的原因是,如果没有它,对该recIIFE()函数的调用将不会this设置为myObj.

对“递归”函数的初始调用(它不是真正的递归,但我现在先放一张幻灯片)是注释中标记为“第二”的那个。该外部.bind(this)()创建了该函数的第一个绑定版本,它绑定了thisin的值myMethod(),即外部对象myObj

现在,在第一次调用中recIIFE(),没有传递任何参数,因此使用默认值 0。设置myArr[0]

接下来setTimeout()是电话。里面recIIFE(),函数名(“recIIFE”)仍然指的是预绑定的函数;换句话说,不是从 中创建并立即调用的函数myMethod(),而是原始函数。因此,它必须再次绑定,定时器调用才能正常工作。的值this仍然是myObj,所以这很简单。

最后,关于如何调用的决定setTimeout()只是检查索引与值数组长度的比较,以便在耗尽所有其余元素后从第一个元素重新开始。


不是真正递归的原因recIIFE()是在任何给定时间只有一个激活函数正在运行。从来没有一堆调用中的调用。除非您非常关心术语,否则这并不是什么大问题。


推荐阅读