[英]Scope resolution in Javascript using 'with' keyword
当使用'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语句是一个问题,但我想弄清楚的主要问题是,在alert语句的范围解析期间,'aptNum'和'x'都应该是由于吊装而在本地范围内未定义,因此它们应被视为“已声明但未定义”。
但是,aptNum输出为'2'。
在with
块中,变量aptNum
被address.aptNum
遮蔽,而x
指的是局部变量(从不address.x
,因为没有这样的属性)。
考虑到并提升,您的代码相当于:
var x = 90;
function test1(){
var aptNum; // hoisted
var x; // hoisted
var address = {
street: 'Haight',
aptNum: 2
};
with (address){
// any reference to aptNum or street inside the with block
// is actually referencing address.aptNum and address.street
alert(aptNum + ":" + x); // this outputs 2 : undefined.
// as expected, because there is no address.x
// and the local x is undefined at this point
aptNum = 100; // this assigns to address.aptNum
// the variable aptNum is shadowed by address.aptNum
x = 10; // this assigns to the local x inside the function
// (again because there is no address.x)
}
}
从小提琴:
with(address){
$('#output').text('aptNum : ' + aptNum + ", x : " + x );
var aptNum = 100,
x = 10 ;
}
变量x
在with
语句的主体中被重新声明(参见前面的var
关键字)。 变量声明被提升,因此x
被临时定义为undefined
,然后在已经记录该值之后最终重新定义为10
。
在这个更新的小提琴中,我将变量声明语句更改为一个简单的赋值语句,它产生了将x
的值记录为90
的预期行为。 见http://jsfiddle.net/ftK2Z/3/
建议不要使用with,并且在ECMAScript 5严格模式下禁止使用。 建议的替代方法是将要访问其属性的对象分配给临时变量。
它不喜欢有一个全局变量。 我认为这是因为x超出了地址对象的范围。 您可以将参数传递给函数,它可以工作。
var x = 90;
test(x);
示例: jsFiddle
有关JavaScript的更多信息
我猜你甚至在声明x
之前调用了x
(它将被视为address
的属性)。 x
在with
范围不指x
的功能外声明。 当然,引擎正在尝试读取当前不存在的address.x
的值。 这就是原因。 关于with
,因为aptNum
是“re',宣布为在该范围内的变量,它并不是指address
的aptNum
。
编码
alert(aptNum + ":" + x);
var aptNum = 100,
x = 10 ;
是var
-ing aptNum
和x
的内with
。 var
被提升,所以它也可以被视为
var aptNum, x;
alert(aptNum + ":" + x);
aptNum = 100, x = 10;
现在很容易理解为什么它们是undefined
。 你可能不想在这里使用var
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.