【问题标题】:bind(this) inside recursive IIFE - what is it exactly doing?递归 IIFE 中的 bind(this) - 它到底在做什么?
【发布时间】:2019-09-08 12:55:40
【问题描述】:

我有一个具有一个属性和一个方法的对象。该方法包含一个带有默认参数的递归 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(this)() 真的应该只是.call(this)

标签: javascript recursion this bind iife


【解决方案1】:

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

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

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

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

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


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    • 2015-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多