2012-07-17 69 views
3

我有一个.js文件,我正在使用NodeJS执行。这里是我的文件的内容:在Javascript中需要帮助理解(词法)变量作用域

var ctry = "America"; 

function outer(msg) { 
    console.log(msg + " " + ctry) ; 
    var ctry = "Canada" ; 
} 
outer("God Bless"); 

当我运行这个文件,我希望看到“上帝保佑美国”,而是,我看到了“上帝保佑未定义”。

如果我注释掉内部var ctry =行,我会得到“上帝保佑美国”,如果我将内部var ctry =行移到console.log上面,我会得到“God Bless Canada”。最后两种情况似乎是合乎逻辑的,但为什么在console.log之后var ctry的定义会导致ctry在上面的代码中被设置为underfined?

回答

5

的局部变量(ctry你的情况)的范围是在声明它的功能整个(也就是说,仿佛变量均在函数的顶部声明)。上面的代码是语义上是一样的:

function outer(msg) { 
    var ctry ; 
    console.log(msg + " " + ctry) ; 
    ctry = "Canada" ; 
} 

现在为什么你在输出中获得undefined它应该是清楚的。

+0

为了澄清,任何var声明都被提升到函数的顶部。实际分配发生在其写入的行上。你重新声明变量是一个局部变量,而不是使用全局变量,因为你使用了关键字var。如果你没有用关键字var重新声明ctry,它会像你期望的那样使用全局变量来工作。 – dqhendricks 2012-07-17 22:20:16

+0

是的。我认为函数定义会被提升,但不知道var声明(局部变量)也会被提升。谢谢 – bachposer 2012-07-17 23:25:10

2

当你说var ctry里面的一个函数(只要它在函数内部并不重要),那么会发生什么是在函数内部调用ctry(再次,无所谓)将引用内部变量,而不是全局变量。问题是,JS解释器只能看到一个变量的定义,但不会用值(加拿大)初始化它,直到它执行该行,因此在console.log中它尚未定义。