需要帮助理解Javascript中的(词汇)变量范围吗
我有一个用NodeJS执行的.js文件。以下是我的文件内容:需要帮助理解Javascript中的(词汇)变量范围吗,javascript,scope,lexical,Javascript,Scope,Lexical,我有一个用NodeJS执行的.js文件。以下是我的文件内容: var ctry = "America"; function outer(msg) { console.log(msg + " " + ctry) ; var ctry = "Canada" ; } outer("God Bless"); 当我运行这个文件时,我希望看到“上帝保佑美国”,但相反,我看到的是“上帝保佑未定义” 如果我注释掉内部变量ctry=行,我会得到“上帝保佑美国”,如果我将内部变量ctry=行移到
var ctry = "America";
function outer(msg) {
console.log(msg + " " + ctry) ;
var ctry = "Canada" ;
}
outer("God Bless");
当我运行这个文件时,我希望看到“上帝保佑美国”,但相反,我看到的是“上帝保佑未定义”
如果我注释掉内部变量ctry=行,我会得到“上帝保佑美国”,如果我将内部变量ctry=行移到console.log上方,我会得到“上帝保佑加拿大”。最后两种情况似乎是合乎逻辑的,但为什么console.log之后的var ctry定义会导致上述代码中的ctry设置为欠定义?局部变量的范围(
ctry
在您的情况下)是声明该变量的整个函数(即,好像该变量是在函数顶部声明的)。上面的代码在语义上与以下代码相同:
function outer(msg) {
var ctry ;
console.log(msg + " " + ctry) ;
ctry = "Canada" ;
}
现在应该很清楚为什么在输出中得到
未定义的。当你在函数中说var-ctry
(只要它在函数中,它在哪里都不重要),那么发生的是在函数中对ctry
的任何调用(同样,在哪里也不重要)都会引用内部变量,不是全球性的。问题是,JS解释器只看到变量的定义,但在执行该行之前不会用值(加拿大)初始化它,因此在console.log
中,它还没有定义。为了澄清,任何变量声明都会被提升到函数的顶部。实际赋值发生在它所写的行上。您正在将变量重新声明为局部变量,而不是使用全局变量,因为您使用了关键字var。如果您没有使用关键字var重新声明ctry,则使用全局变量将按照您的预期工作。是的。我以为函数定义会被提升,但不知道var声明(局部变量)也会被提升。非常感谢。