2017-04-17 93 views
0

我的前言说我知道使用with是非常不鼓励,我也不打算使用它。我只是想知道它是如何工作的(我试图找出javascript中的范围)。变量声明在一个With块

如果我有一些像这样的代码:

function foo(obj) { 
    with (obj) { 
     b = 2; 
    } 
} 

var o1 = { 
    a: "something" 
}; 

foo(o1); 
console.log(o1.b) // This outputs undefined (makes sense) 
console.log(b) // This outputs 2 (makes sense) 

但是,如果我改变富来是这样的:

function foo(obj) { 
    with (obj) { 
     var b = 2; // I use var b instead of b 
    } 
} 

当我通过O1为foo,再次,O1没有属性b。为什么是这样?我认为使用var会在obj的范围内声明b,所以该属性将在o1中而不是在全局范围内创建。

回答

2

var声明被吊销。所以,你正在执行的是相当于

function foo(obj) { 
    var b; 
    with (obj) { 
     b = 2; 
    } 
} 

不要紧,该声明是with块内。 §9.2.12描述了评估函数体时会发生什么。在步骤11/12中,收集所有变量声明。一个with声明只是“转发”其中的所有声明(see spec)。

1

变量声明(使用var)不尊重块范围,而是将hoisted置于范围的顶部。就编译器/解释器而言,您的代码实际上是:

function foo(obj) { 
    var b = undefined; 
    with (obj) { 
     b = 2; 
    } 
}