概念:
with的初衷是为了避免冗余的对象调用,
它的作用是将代码的作用域设置到一个特定的对象中。
它的目的主要是为了简化多次编写同一个对象的工作。
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
// 上面几行代码都包含 location 对象。
如果使用 with 语句,可以把上面的代码改写成如下所示:
with(location){
var qs = search.substring(1);
var hostName = hostname;
var url = href;
}
在这个重写后的例子中,使用 with 语句关联了 location 对象。
这意味着在 with 语句的代码块 内部,每个变量首先被认为是一个局部变量,
而如果在局部环境中找不到该变量的定义,
就会查询 location 对象中是否有同名的属性。
如果发现了同名属性,则以 location 对象属性的值作为变量的值。
在《JavaScript权威指南》(第五版, David Flanagan, P109)给出了指出:
with语法用于暂时修改作用域链,他能够将Object添加到作用域头部,然后执行statement语句,再把作用域链恢复到原始状态
with (Object)
statement
那么使用with会出现什么问题呢?(问题的根源还是来源于作用域链的改变)
1:性能问题:
是否使用with,性能上有特别明显的差异。
2:不可预测性:
function foo(a){
with(a){
console.log(a);
}
}
foo("sword"); // "sword"
foo({}); // Object {}
foo({a: "sword"}); // "sword"
在这个例子中,字符串和对象都没问题,
可是当传入带有a属性的对象时,就获取这个对象中的a属性了,
跟我们所预计的结果不一致
3:在with语句中声明的变量,并不属于with指定的参数对象:
var a ={};
with(a){
x = 'sword'
var y = 'wang';
}
console.log(a.x); // undefined
console.log(a.y); // undefined
console.log(window.x); // "sword"
console.log(window.y); // "wang"
在这个例子中with声明的变量实际上是被添加到外层的function中的
仅仅通过标识符及其上下文,无法确定一个with中的标识符指向什么,这是with被废弃的真正原因。它强行混乱了上下文使得程序的预测和解析变得困难。
参考文章:swordair.com/javascript-… 参考书籍:《JavaScript高级程序设计》(第3版, Nicholas C.Zakas, P60)