27

对不起这个问题,但这个问题真的搞砸了我的一天。

以下代码按照应有的方式提醒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 在执行函数之前“预先声明”所有变量是真的,甚至在条件不满足的情况下声明的变量也是如此?

4

6 回答 6

24

在 javascript 中,您应该知道有一种叫做HOISTING的东西。

这实质上意味着,当您声明任何局部变量时,变量声明会自动带到作用域的顶部。

例如:-

var globalId='10';
function check(){
alert(globalId); var globalId; }
check(); 

更改为 -

var globalId='10';
function check(){
var globalId;
alert(globalId);}
check(); 

由于 globalID 仍未分配任何值,因此它在输出中返回 undefined 。局部变量总是优先于同名的全局变量。

于 2011-03-31T11:36:43.197 回答
17

是的,函数中任何地方声明的所有变量都是该函数的局部变量,并且存在于函数的代码中;它们将优先于同名的全局变量使用。

来自https://developer.mozilla.org/en/JavaScript/Guide/Values,_Variables,_and_Literals#Variable_Scope

JavaScript 没有块语句范围;相反,它将是块所在的代码本地的。[...] JavaScript 中变量的另一个不同寻常之处在于,您可以引用稍后声明的变量,而不会出现异常。这个概念被称为提升;JavaScript 中的变量在某种意义上被“提升”或提升到函数或语句的顶部。

于 2011-03-31T11:36:02.140 回答
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(); 


yopurvar语句位于函数定义末尾的事实并没有改变任何东西:全局变量被整个函数屏蔽了

因此,对于函数的整个执行,globalId变量将引用本地变量,而不是全局变量。

但是,在该函数之外,全局变量仍然存在——因为该var语句,从函数内部看不到它。

于 2011-03-31T11:35:51.263 回答
4

As has been said, conforming to JavaScript scoping rules, the local variable masks the global for the entire function. However the global variable may be accessd, try the following

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(); 
于 2011-03-31T11:43:34.813 回答
0

您在函数范围内声明 NEW 变量globalId,因此它未定义,这是正确的。不,它不会杀死你的全局变量,你可以通过alert(globalId);check();调用后添加来检查它。

于 2011-03-31T11:36:18.987 回答
0

好像Javascript首先执行了整个函数,只是为了看看是否有任何变量“可能”被声明

这就是答案,或多或少。JavaScript 解释器在每个范围内查找变量声明,然后将它们“移动”到范围的顶部。

于 2011-03-31T11:41:10.217 回答