先说结论
with语句作用: 扩展一个语句的作用域链。
ES5严格模式中禁止使用with语句
优点:
性能: with作用域内的变量都来自with提供的作用域时,减少不必要的指针路径解析运算.
缺点:
+性能: with作用域内的变量不是来自with提供的作用域时,查找起来很慢,且导致数据泄露
+语法:
1.语义不明
2.无法向前兼容
语法
with (expression) {
statement
}
扩展一个With Block作用域
no_with.png没有with的时候只有2个作用域
with1.png增加with语句后,变成3个作用域了,这就是传说中的扩展了语句的作用域
数据泄露
function test(){
with(Math){
a = PI*4; // a是LHS(左值引用查询),执行完这一行后全局变量上会创建一个全局变量
}
}
test();
a是左值引用查询,查找a变量时:
首先在With Block作用域上查找,没有
接着在Local作用域上查找,没有
最后到了Global作用域上查找,没有. 此时,会在Global上创建一个全局变量a.
为什么会创建全局变量a,因为:
不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下)
不成功的RHS引用会导致抛出 ReferenceError 异常。
语义不明
function f(x, o) {
with (o)
print(x); // x到底是形参里的x? 还是o.x?
}
无法向前兼容
function f(foo, values) {
with (foo) {
console.log(values)
}
}
f([1,2,3], {a:1})
ES6中Array.prototype扩展了values方法,那么console.log中的values将会指向foo.values,而不是形参中的values
网友评论