【问题标题】:Why a nested IIFE is not creating closure?为什么嵌套的 IIFE 没有创建闭包?
【发布时间】:2017-02-08 15:27:10
【问题描述】:

我正在阅读 this resource,试图了解闭包在 Javascript 中的工作原理。

我了解到,每次在其正常词法范围之外调用函数时,它都会创建闭包,从而能够访问封闭的函数变量并使用它们来存储状态。

这在下面的my_module.incrCounter(); 中有效(不断增加计数器),但是为什么它在my_module.incrLocalCounter(); 中不起作用,每次都返回1?

incrLocalCounter 内部的 IIFE 不应该在 local_counter 上创建闭包吗?

var my_module = (function tlModule(){

  var counter = 0;

  function incrCounter(){

    counter++
    console.log(counter);

  };



  function incrLocalCounter(){

    var local_counter = 0;

    (function () {
      local_counter++
      console.log(local_counter)
    })();

  };

  return {

    incrCounter: incrCounter,
    incrLocalCounter: incrLocalCounter

  }

})();

【问题讨论】:

  • 每次在其正常词法范围之外调用函数时,它都会创建闭包——这并不正确。函数调用本质上总是会创建一个闭包,尽管在许多情况下闭包是空的。

标签: javascript


【解决方案1】:

您的“嵌套”IIFE 每次都会记录 1,因为在 IIFE 运行之前,递增的变量总是初始化为 0。也就是说,在那个嵌套函数中,local_counter 总是从 0 开始。

如果您将local_countervar 声明移到incrLocalCounter() 之外,那么您会看到它增加。或者,您可以让 incrLocalCounter() 返回一个 function 并将其作为您返回的属性值:

function incrLocalCounter(){

  var local_counter = 0;

  return function () {
    local_counter++
    console.log(local_counter)
  };

};

return {

  incrCounter: incrCounter,
  incrLocalCounter: incrLocalCounter() // <-- call the function

}

【讨论】:

    【解决方案2】:

    incrLocalCounter 内部的 IIFE 不应该在 local_counter 上创建闭包吗?

    确实如此。 local_counter 当时在 0。然后它通过执行 IIFE 将其从 0 增加到 1。然后它返回1。每次调用incrLocalCounter 时,它都会执行相同的顺序(包括将local_counter 设置为0)。区别不在于incrLocalCounter 有一个IIFE;区别在于被递增的变量是否在函数内被重置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      相关资源
      最近更新 更多