对不起这个问题,但这个问题真的搞砸了我的一天。
以下代码警告 10 :
var globalId='10';
function check(){
alert(globalId);
}
check();
但是下一个代码警告 undefined :
var globalId='10';
function check(){
alert(globalId);
var globalId;
}
check();
我知道如果我在函数中声明一个变量是一个局部变量,但是如果我已经将它声明为全局变量,那么我的警报怎么说 undefined ?
这是一个简单的例子,但在我的原始代码中,我在函数的开头之间做了很多东西,然后我检查了globalId
是否定义了很长时间,否则定义它: if(!globalId){var globalId;}
这意味着位于函数顶部的警报生成未定义,就好像JavaScript首先执行整个函数一样,只是为了查看是否可以声明任何变量,如果是,则声明它们,因此我的警报指向“未声明”变量。
任何人都可以向我解释为什么会发生这种情况,并且如果JavaScript在执行函数之前“预先声明”了所有变量,那么甚至在甚至不满足的条件下声明的变量也是如此?
答案 0 :(得分:23)
在javascript中,你应该知道有一些叫做 HOISTING 的东西。
这实质上意味着,当您声明任何局部变量时,变量声明会自动传递到范围的顶部。
例如: -
var globalId='10';
function check(){
alert(globalId); var globalId; }
check();
对 -
的更改var globalId='10';
function check(){
var globalId;
alert(globalId);}
check();
由于globalID仍未分配任何值,因此它会在输出中返回undefined。局部变量总是优先于具有相同名称的全局变量。
答案 1 :(得分:16)
是的,函数中任何地方声明的所有变量都是该函数的本地变量,并且存在于整个函数的代码中;它们将优先用于同名的全局变量。
来自https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals#Variable_Scope:
JavaScript没有块语句范围;相反,它将是块所在代码的本地代码。 [...] JavaScript中变量的另一个不同寻常之处在于,您可以引用稍后声明的变量,而不会出现异常。这个概念被称为吊装; JavaScript中的变量在某种意义上是“被提升”或被提升到函数或语句的顶部。
答案 2 :(得分:13)
在你的第二部分代码中,局部变量掩盖了全局变量。
var globalId='10';
function check() {
// Your are defining a local variable in this function
// so, the global one is not visible.
alert(globalId);
var globalId;
}
check();
yopur var
语句位于函数定义末尾的事实不会改变任何内容:全局变量被遮盖用于整个函数。
因此,对于函数的整个执行,globalId
变量将引用本地变量,而不是全局变量。
在该函数之外,全局变量仍然存在 - 由于var
语句,它不会从函数内部看到。
答案 3 :(得分:3)
如前所述,符合JavaScript作用域规则,局部变量会屏蔽整个函数的全局变量。但是,可以访问全局变量,请尝试以下
var globalId='10';
function check() {
// Your are defining a local variable in this function
// so, the global one is not visible.
alert('Local : ' + globalId + ', Global : ' + window.globalId);
var globalId;
}
check();
答案 4 :(得分:0)
你在函数范围内声明了新的变量globalId
,所以它是未定义的,这是正确的。不,它不会杀死您的全局变量,您可以在alert(globalId);
调用后添加check();
来检查它。
答案 5 :(得分:0)
好像Javascript首先执行整个函数,只是为了查看是否有任何变量'可能'被声明
这或多或少都是答案。 JavaScript解释器在每个范围内查找变量声明,然后将它们“移动”到范围的顶部。
答案 6 :(得分:0)
var globalId='10';
function check(){
let globalId = '5';
alert(globalId);
}
check();
// use let to set a local variable between any {}