【问题标题】:Issue with scope and closures in JavaScriptJavaScript 中的作用域和闭包问题
【发布时间】:2009-11-23 10:29:21
【问题描述】:

我的问题更多是关于 JavaScript 的作用域,而不是闭包。

让我们看下面的代码:

var f = function () {
    var n = 0;
    return function () {
        return n++;
    };
}();

console.log(f());
console.log(f());

以上代码输出:

0
1

从上面的代码可以看出,f(自调用)返回一个函数,创建了n的闭包。


因此,它可以与匿名函数一起使用;因此,然后我用一个命名函数尝试了它:

var f2 = function () {
    return n++;
};

var f = function () {
    var n = 0;
    return f2;
}();

console.log(f2()); // <= [n is not defined]

上面的代码不起作用,错误为n is not defined。我认为这是一个范围界定问题;但我不知道究竟是为什么;

为什么作用域与匿名的内部函数相同,但不适用于命名的外部函数?

另外,在第二个例子中,我是在创建一个闭包吗?

【问题讨论】:

    标签: javascript function scope function-pointers closures


    【解决方案1】:

    在第一个示例中创建了闭包,因为匿名函数中的代码使用了在匿名函数之外声明的局部变量。

    在第二个示例中,函数f2 中的n 变量的范围在函数声明时已经确定。创建具有相同名称的局部变量不会改变函数的含义,并且在另一个函数中使用该函数不会改变它的作用域。因此,该函数不使用局部变量。

    【讨论】:

      【解决方案2】:
      【解决方案3】:

      f2 无法确定变量 n 应该放在哪里。

      在第一个示例中,匿名函数在函数 f 内部,在第二个示例中 - 外部(f2 而不是匿名)。因此,f2 无法访问变量 n,因为它在另一个范围内并且不可访问(不可见)。试试把 f2 声明 inside f.

      【讨论】:

        【解决方案4】:

        在你的第二个例子中,你没有创建一个闭包,你只是返回一个全局变量。 f2 没有被关闭,因为它是在更一般的(在本例中为全局)范围内声明的,而 n 是在更具体的范围内声明的。闭包可以在作用域链“漏斗”的下游,而不是向上,并且只有在所有相关实体都定义在同一作用域中时才有效。

        【讨论】:

          【解决方案5】:

          我们可以重写您的第二个示例以使其与命名函数一起使用:

          var f = function() {
              var n = 0;
              var f2 = function() {
                  return n++;
              };
              return f2;
          }();
          console.log(f());
          console.log(f());
          

          这将像您的第一个示例一样输出 0 和 1。

          正如其他答案所述,它与函数的命名或匿名无关,它与 n 和 f2 的范围有关。由于您在示例中在 f 之外声明了 f2,因此它无法访问在 f 范围内声明的变量 n。

          【讨论】:

            猜你喜欢
            • 2017-06-18
            • 2010-10-12
            • 2017-04-14
            • 1970-01-01
            • 2011-01-19
            • 2014-02-13
            • 2013-01-01
            • 1970-01-01
            • 2018-09-09
            相关资源
            最近更新 更多