【发布时间】:2013-05-15 23:25:04
【问题描述】:
使用 'with' 关键字时,Javascript 中的提升和作用域似乎有一种奇怪的行为。
我知道“with”的使用被认为是禁忌,但在其中一个框架中遇到了这个问题并且不得不处理它。不过,
谁能解释为什么如果我们有一个'with'块,声明但未定义的变量是使用with对象解析的,但闭包变量不是这种情况。
要演示,请参见以下代码的输出:http://jsfiddle.net/ftK2Z/1/
var x = 90;
function test1(){
var address = {
street: 'Haight',
aptNum: 2
};
with (address){
alert(aptNum + ":" + x); // this outputs 2 : undefined.
var aptNum = 100,
x = 10 ;
}
}
用谷歌浏览器检查。
注意:我了解 JS 提升,并了解为什么在警报之后使用 var 语句是一个问题,但我想弄清楚的主要问题是, 在警报语句的范围解析期间,由于提升,“aptNum”和“x”都应该在本地范围内未定义,因此它们应该被视为“已声明但未定义”。
但是,aptNum 仍然输出为 '2'。
【问题讨论】:
-
JavaScript 没有块作用域。
with中的var aptNum是封闭函数的局部变量。提供给with的对象的属性可以作为块内的变量访问,这就是您获得2的原因。您无法使用var向对象添加新属性,但您可以在不直接引用对象的情况下更新现有属性。 -
@squint 谢谢。这似乎以某种方式创建了一个块范围,其中“with”对象属性填充在本地范围中。然后范围在块之后消失。但是由于 JS 中没有块作用域,这是一种奇怪的行为
-
是的,它的行为很奇怪而且令人困惑,这就是人们建议避免它的原因。不过它可能很有用。它是一种范围,但不是典型的变量范围。
var不受限制。
标签: javascript jquery google-chrome javascript-engine