2012-12-04 24 views
1

可能重复:
Redeclare JavaScript Variable新来JS,试图了解吊装

我的下一段代码:

var i = 11; 
alert(i); 
function a(){ 
    alert(i); 
    var i = 2; 
    alert(i); 
} 
a() 

第二alert(i)(内功能)产生undefined。我猜它与JS引擎通过代码运行的方式有关 - 也许它不会首先存储变量,然后再通过代码行?

无论如何,我认为这不是一个问题是JS,因为它支持吊装。我可能弄错了 - 有没有人关心解释?

谢谢!

+0

有几个关于这个问题重复的问题:这个问题(http://stackoverflow.com/questions/13630373/will-i-have-any-problems-if- i-declare-the-same-variable-multiple-times/13630592#13630592)和[this one](http:// stackoverflow。com/questions/13626094/redeclare-javascript-variable/13626288#13626288)处理此事 –

回答

4

JavaScript确实将声明提升到它们出现的范围的顶部,但分配发生在您期望它们的位置。您的代码有效地解析如下:

/* Function declarations are hoisted first, which is why you can invoke a 
    function before it appears to be defined in the source */ 
function a() { 
    var i; // Declaration is hoisted (this i shadows the outer i) 
    alert(i); 
    i = 2; // Assignment to local i happens in place 
    alert(i); 
} 
var i; // Declaration is hoisted (at this point, i === undefined) 
i = 11; // Assignment happens in place 
alert(i); 
a(); 

这是详细的in the spec。当进入一个新的执行上下文中,发生以下情况:

对于每个VariableDeclarationVariableDeclarationNoIn d代码,在源文本顺序做

  • DN标识符 in d
  • varAlreadyDeclared是调用env的传球DN作为参数 HasBinding具体方法的结果。
  • 如果varAlreadyDeclaredfalse,然后
    • 呼叫env的 CreateMutableBinding传递DNconfigurableBindings作为参数具体方法。
    • 呼叫env的 SetMutableBinding传递DNundefined,并严格作为参数具体方法。
+0

当解释器遇到一个没有关键字'var'的函数变量之前不会出现悬挂? OP正在创建一个新的变量'i',它是函数范围的,对吗? –

+0

@limelights - 在进入任何执行上下文时发生吊装。当控制进入'a'函数时,解释器会在开始执行代码之前查找任何声明并在新执行上下文的环境记录中为其标识符创建绑定。 –

+1

事实上,函数a()的第一行'var i;'对函数有一个局部范围,所以直到'i = 2;' – ncremins