在Javascript中,我可以在声明之前使用变量吗?

时间:2013-11-26 15:12:37

标签: javascript variables scope switch-statement

如果在定义之前我可以在JS中使用变量,我一直想知道, 如下:

var country = "USA";
switch (country) {
    case "USA":
        country = i;
    case "blach":
        //not finished yet
}
/*
  put a whole
  bunch more code here
*/
var i = 10;

这有效吗?是允许的吗?如果是这样,它的技术术语是什么?

4 个答案:

答案 0 :(得分:24)

这是一种名为hoisting的JavaScript引擎使用的技术。解析器将在运行之前读取整个函数,并且将执行任何变量声明(即使用var关键字),就好像它们位于包含范围的顶部一样。所以你的代码就像:

var country;
var i;

country = "USA";
switch (country) {
case "USA":
    country = i;
case "blach":
    //not finished yet
}

i = 10;

因此,i在整个范围内声明,但在undefined语句运行之前,其值为i = 10

在ECMAScript术语中,当调用函数时,函数的新词法范围在任何函数的代码运行之前构建其VariableEnvironment。在ECMAScript 10.5, step 8

  

8。对于代码中的每个 VariableDeclaration ... d ,在源文本顺序中执行

     

一个。设 dn 为d。

中的标识符      

...

     

我。调用 env 的CreateMutableBinding具体方法,将 dn configurableBindings 作为参数传递。

     

II。调用 env 的SetMutableBinding具体方法,将 dn undefined strict 作为参数传递。

这是非常满口的,但基本上它说:

  

在运行函数之前,请查看函数的源代码,了解var [identifierName]之类的声明。

     

对于您找到的每个声明,在函数的作用域中创建一个新变量,声明中使用名称[identifierName],然后将其值设置为undefined

答案 1 :(得分:7)

它被称为variable hoisting,这是一个很好的概念,因为它偶尔可以创建很难追踪的错误

例如:

var stuff = 'stuff';
function() {
 console.log(stuff); //outputs 'undefined'
 var stuff = 'other stuff';
 console.log(stuff); //outputs 'other stuff'
}

第一个console.log输出undefined,因为函数中的var stuff 被提升到函数的顶部。

//theoretical compiled output
var stuff = 'stuff';
function() {
 var stuff; //has not been defined
 console.log(stuff);
 stuff = 'other stuff'; //defined here
 console.log(stuff);
}

如果不知道变量提升,这个结果可能会令人困惑。

因此,如果您查看专业开发的JavaScript代码,通常会看到函数中的所有变量都在顶部声明。

答案 2 :(得分:3)

是。在JavaScript中,变量为hoisted

  

变量语句声明按10.5中定义的方式创建的变量。 变量在创建时初始化为未定义。具有Initialiser的变量在执行VariableStatement时被赋予其AssignmentExpression 的值,而不是在创建变量时。 ES5 §12.2
  其中10.5步骤8是感兴趣的部分

答案 3 :(得分:2)

这些家伙的答案是正确的。但是,对于您的示例,值得注意的是countryundefined。因为aspillers提到你的代码行为如下

var country;
var i;

country = "USA";

switch (country) {
case "USA":
    country = i;
case "blach":
    //not finished yet
}

i = 10;
alert(country) //undefined;

但是当您的case语句针对“USA”运行时,i未定义,因此已将其分配给country。请在此fiddle中尝试。

我想你只需要知道虽然变量声明是悬挂的,但值赋值不是。