2012-07-12 46 views
8

如果我这样做:本地的Javascript范围界定问题

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

这是怎么发生的?

+0

我不知道为什么它确实是,但我试着用'VAR一个= window.a'并适当地表现 – Ibu 2012-07-12 17:32:35

+0

@Ibu嗯这是奇数... – Neal 2012-07-12 17:33:03

+0

,因为所有的全局变量在窗口范围 – jagm 2012-07-12 17:36:48

回答

10

var a = a;实际上是由于变量提升造成的var a; a = a;。这意味着在分配时,旧的a已被新的阴影(undefined)所覆盖。

,以避免类似的问题被传递值作为参数的最简单方法:

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

如果a是一个全局变量,你也可以使用var a = window.a;woz suggested - 但由于具有全局变量通常是一个坏主意更好地保持与参数。

+0

因此,如何将我做到这样,我的本地变量和全局变量在本地函数作用域的开始处是相等的?我需要使用临时变量吗? – Neal 2012-07-12 17:36:06

+1

看我的编辑。你不能使用临时变量,因为无论你做什么,只要你的函数中有'var a',外层'a'就不能再被访问了。 – ThiefMaster 2012-07-12 17:36:51

+0

Ooohh我忘了参数:-P Duuuuh。 '+ 1' – Neal 2012-07-12 17:37:31

0

有一个JavaScript变量提升,让你的代码中执行这样的容貌:

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

所以,首先你有局部变量为未定义,然后您分配不确定的变量a

5

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

变得NaN,因为在分配:

var a = a; 

右侧a它实际上指的是a在局部范围。

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

由于它是同一个变量,它拥有undefined值,当你尝试任何数量添加到该值,就NaN

console.log(undefined + 0); 
2

在JavaScript中,目前execution context(其中包括像变量范围)之前您的代码开始执行。

这对您意味着什么是您的本地变量名称首先被分配。由于的提升,在当前执行上下文中,来自var语句的任何地方的函数中的任何地方都被初始化为undefined。 (功能语句也在此步骤中初始化。)

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

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