可能重复:
variable hoisting
var a = "global";
//version 1
function changeGlobal(){
alert(a); //why is 'a' undefined here?
if(a){
var a = "local";
alert(a);
}
}
//version 2
function changeGlobal(){
alert(a); //why is 'a' 'global' here? what diff does 'var a="local"' make?
if(a){
//var a = "local";
alert(a);
}
}
changeGlobal();
问题是内联的。帮助我理解变量范围。
答案 0 :(得分:4)
在javascript中,变量声明被“提升”到函数的顶部,与你声明它们的位置无关。
因此,在changeGlobal的第一个变体中,当您声明var a = "local"
时,a
变量声明会被提升到顶部。变量的赋值也不会被提升,所以当你提醒a
时,它是一个未赋值的变量,因此未定义。
即,
function changeGlobal(){
alert(a); //why is 'a' undefined here?
if(a){
var a = "local";
alert(a);
}
}
相当于
function changeGlobal(){
var a; // hoisted here (not assigned a value yet)
alert(a); //why is 'a' undefined here?
if(a){
a = "local"; // only assigned a value here
alert(a);
}
}
答案 1 :(得分:2)
在版本1中,您声明了一个名为a
的局部变量,该变量优先于a
函数中的全局changeGlobal
。即使它是在alert(a);
电话之后定义的,其定义仍然是“提升”。直到范围的开头,但直到var a = "local";
行才初始化。这就是alert(a);
显示undefined
。
在版本2中,因为没有本地a
,所以您始终处理在函数运行之前已初始化的全局a
。
答案 2 :(得分:1)
JavaScript具有词法作用域,其中变量可以从var
编辑的程序/函数中取消引用,然后向下(因为,引用它不会抛出ReferenceError
。
{1}}语句也将被提升,初始值设置为var
。
或者在外行术语中,变量的范围限定在它们定义的函数中,并且所有变量在函数执行期间的任何时候都可用,尽管可能尚未分配值。
组合,这是你正在观察的 - 一个局部var遮蔽全局var。