【问题标题】:Local Javascript scoping issue本地 Javascript 范围问题
【发布时间】:2012-07-12 17:28:04
【问题描述】:

如果我这样做:

var a = 0;

(function () {
    var a = a; //want to make local a = global a
    ++a;
    console.log("fn",a);
})();

console.log(a);​

输出是:

fn NaN
0

为什么自执行函数内部的a变成NaN

我知道如果我这样做会很好:

(function () {
    var b = a;
    ++b;
    console.log("fn",b); // fn 1
})();

但如果我走第一个版本的路,它就有NaN 的问题。

为什么会这样?

【问题讨论】:

  • 我不知道为什么会这样,但我尝试使用 var a = window.a 并且它的行为正常
  • @Ibu 嗯,这很奇怪......
  • 因为所有全局变量都在窗口范围内

标签: javascript scope


【解决方案1】:

var a = a; 实际上是 var a; a = a; 由于变量提升。这意味着在分配时旧的a 已经被新的undefined 遮蔽。

避免此类问题的最简单方法是将值作为参数传递:

(function (a) {
    ++a;
    console.log("fn",a);
})(a);

如果a 是一个全局变量,您也可以像woz suggested 一样使用var a = window.a; - 但由于拥有全局变量通常是个坏主意,最好保留参数。

【讨论】:

  • 那么我该如何让我的局部变量和全局变量在局部函数作用域的开始处相等?我需要使用临时变量吗?
  • 查看我的编辑。您不能为此使用临时变量,因为无论您做什么,只要您的函数中有 var a,外部的 a 就无法再访问了。
  • 噢,我忘记了参数:-P Duuuuh。 +1
【解决方案2】:

函数表达式中的a 变量遮蔽在外部作用域上声明的a 变量。

它变成NaN,因为在赋值中:

var a = a;

右边的a实际上是指本地范围内的a

变量声明在函数实际开始执行之前完成,这通常称为“提升”。

因为它是同一个变量,所以它持有undefined的值,当你尝试向这个值添加任何数字时,它变成NaN

console.log(undefined + 0);

【讨论】:

    【解决方案3】:

    在 JavaScript 中,当前的execution context(包括变量范围之类的东西)是在您的代码开始执行之前建立的。

    这对您意味着首先分配您的局部变量名称。由于提升,来自var 语句函数中的任何地方 的标签在当前执行上下文中被初始化为undefined。 (函数语句也在这一步初始化。)

    接下来,您的代码实际上开始执行。 a 标签已在当前执行上下文中保留,因此 var a = a; 只需将本地 a未定义)分配给自身。

    var a = window.a 之所以有效,是因为您通过直接访问全局范围来回避范围问题。但是,这在非浏览器环境(如 Node)中不起作用,因为没有 window; Node中的全局对象是global

    【讨论】:

      【解决方案4】:

      javascript中有一个变量提升,所以你的代码在执行过程中是这样的:

      (function () {
          var a;
          a = a; //want to make local a = global a
          ++a;
          console.log("fn",a);
      })();
      

      所以首先你将局部变量 a 作为 undefined,然后你将 undefined 分配给变量 a

      【讨论】:

        猜你喜欢
        • 2015-04-19
        • 2011-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多