4

我正在学习 javascript,我的问题实际上可能不会在任何地方使用,但出于面试目的,我想清楚地理解这一点。下面是代码。第一个警报警报“未定义”,第二个警报是“4”。第二个是可以理解的。我想知道为什么第一个警报没有警报“5”并且未定义?相同的概念是什么?谢谢。

 var x = 5;
 function check(){
     alert(x);
     var x = 4;
     alert(x);
  }
 check();
4

2 回答 2

10

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
于 2013-10-31T17:10:52.653 回答
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 中添加块级范围,但目前还没有在所有浏览器中实现,所以这就是我将它放在一边的原因。

于 2013-10-31T21:17:24.433 回答