8

如果我这样做:

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问题了。

为什么会这样?

4

4 回答 4

12

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

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

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

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

于 2012-07-12T17:35:24.837 回答
6

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

它变成NaN,因为在作业中:

var a = a;

a它实际上指的a是本地范围内的右侧。

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

由于它是同一个变量,因此它保存该undefined值,并且当您尝试将任何数字添加到该值时,它变为NaN

console.log(undefined + 0);
于 2012-07-12T17:36:27.253 回答
2

在 JavaScript 中,当前执行上下文(包括变量范围之类的内容)是在您的代码开始执行之前建立的。

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

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

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

于 2012-07-12T17:38:06.647 回答
0

javascript中有一个变量提升,所以你在执行过程中的代码如下所示:

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

所以首先你有局部变量 a 未定义,然后你将 undefined 分配给变量 a

于 2012-07-12T17:35:43.427 回答