我正在学习 javascript,我的问题实际上可能不会在任何地方使用,但出于面试目的,我想清楚地理解这一点。下面是代码。第一个警报警报“未定义”,第二个警报是“4”。第二个是可以理解的。我想知道为什么第一个警报没有警报“5”并且未定义?相同的概念是什么?谢谢。
var x = 5;
function check(){
alert(x);
var x = 4;
alert(x);
}
check();
我正在学习 javascript,我的问题实际上可能不会在任何地方使用,但出于面试目的,我想清楚地理解这一点。下面是代码。第一个警报警报“未定义”,第二个警报是“4”。第二个是可以理解的。我想知道为什么第一个警报没有警报“5”并且未定义?相同的概念是什么?谢谢。
var x = 5;
function check(){
alert(x);
var x = 4;
alert(x);
}
check();
var
总是被提升(移动)到范围的开头。您的代码等效于:
var x = 5;
function check(){
var x;
alert(x);
x = 4;
alert(x);
}
check();
正如您可以清楚地看到的那样,本地x
隐藏了全局x
,即使本地还没有值(所以第一个警报显示undefined
)。
一点额外的:条件或其他块不影响提升var
声明。
var x = 1;
(function() {
x = 3;
if (false) {
var x = 2; // var will be moved to the begining of the function
}
})()
console.log(x) // 1
JavaScript 有一些概念确实需要一点时间来适应,有时对于一个看似简单的问题的答案是冗长的,但我会尽量做到快速简洁。
在 JavaScript 中,变量由函数限定范围,并且您有两个地方可以“全局”或“局部”限定变量(具有上下文)。Web 浏览器中的全局上下文是“窗口”,因此在您的代码示例var x = 5;
中是一个全局变量。代码中的本地上下文在您的检查函数中,因此检查函数var x = 4;
的局部变量也是如此。如果您有更多功能,那么它们将有自己的功能范围(上下文)等等。请注意,如果在函数内声明变量时忘记了“var”一词,它将成为“全局”变量,请小心。现在我们有了“全局”、“本地”范围,在 Javascript 程序运行之前会发生什么?
在执行代码之前,Javascript 引擎中会发生一些事情,但我们只会看看变量会发生什么。变量被称为“提升”到其功能上下文或范围的顶部。这意味着变量声明被“提升或移动到顶部并分配了值“未定义”但未初始化,初始化保持在原来的位置。这种提升还使变量在它定义的函数中的任何地方都可用。
所以它看起来像这样:
//to be accurate this is hoisted to its functional scope as well
var x;
x = 5;
function check() {
//declaration of 'x' hoisted to the top of functional scope,
//and assigned undefined
var x;
//this will alert undefined
alert(x);
//initialization of variable remains here
x = 4;
//so after the initialization of 'x' this will alert 4
alert(x);
}
check();
快乐编码!!!
顺便说一句:他们有一个名为“让”的新功能,您可以实现它以在我相信 EMCAScript 6 中添加块级范围,但目前还没有在所有浏览器中实现,所以这就是我将它放在一边的原因。