Javascript 函数中变量的作用域和可用性

Javascript 函数中变量的作用域和可用性,javascript,Javascript,我正在学习javascript,我的问题可能不会在任何地方使用,但出于面试目的,我想清楚地理解这一点。下面是代码。第一个警报为“未定义”,第二个警报为“4”。第二个是可以理解的。我想知道为什么第一个警报没有警报“5”和未定义?这背后的概念是什么? 谢谢 var始终提升(移动)到范围的开头。您的代码与此等效: var x = 5; function check(){ var x; alert(x); x = 4; alert(x); } check

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


var
始终提升(移动)到范围的开头。您的代码与此等效:

 var x = 5;
 function check(){
     var x;
     alert(x);
     x = 4;
     alert(x);
  }
 check();
您可以清楚地看到,本地
x
隐藏全局
x
,即使本地
x
还没有值(因此第一个警报显示
未定义的


额外一点:条件或其他块不会影响
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是一个全局变量。代码中的本地上下文在check函数中,因此
var x=4
是check函数的局部变量。如果您有更多的函数,这些函数将有自己的函数范围(上下文)等等。作为警告,如果在函数中声明变量时忘记了“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();
快乐编码


旁白:它们有一个名为“let”的新功能,您可以在EMCAScript 6中实现它来添加块级范围,但到目前为止还没有在所有浏览器中实现,因此我将它放在旁白中

您可以在这里阅读更多关于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();