为什么不使用 javascript with?

2012-12-03 19:49

为什么不使用 javascript with?

by Jun.lu

at 2012-12-03 11:49:00

original http://www.cnblogs.com/idche/archive/2012/12/03/2799355.html

众所周知大家对 with 都没什么好感,而且不推荐使用。

可以收集到的理由有:

下面几条来自 《javascript权威指南》 第 5 版本。

  1:使用with的语句很难优化。
  2:使用with语句速度要比不使用with语句的等价代码的速度慢得多。
  3:在with语句中的函数定义和变量初始化可能产生令人惊讶,和直觉相抵触的行为。
  4:90%(或者更高比例)的with应用场景都可以用其他更好的方式代替。

如何证明以上观点。

  第一点貌似没有什么好的代码实例。(欢迎大家提供)

  第2点:

var a = {
a:{
a:{
a:{
a:{
a:{
a:{
b:
1
}
}
}
}
}
}
};

//取值与赋值 10000
function noWith(){
var obj = a.a.a.a.a.a.a, i=100000, j = 0;
for(; i; i--){
j
= obj.b;
obj.b
= i;
}
}

//取值与赋值 10000
function yesWith(){
var i=100000, j = 0;
with( a.a.a.a.a.a.a ){
for(; i; i--){
j
= b;
b
= i;
}
}
}


var t = new Date().getTime();
//noWith();
yesWith();
console.log(
new Date().getTime() - t);

//运行上面两个函数, 对一个比较深的对象取值与赋值 100000 次

//不使用with: 0-3毫秒(chrome浏览器,可能是V8太NB,我自己都不信了),换了Firefox 大约是7-10毫秒
//使用with: 120-130毫秒之间(chrome), 110-120毫秒(Firefox)

//结论:使用with进行大量运算确实存在一些性能问题,但是10W次的运算估计也很少遇到,大家自己权衡。

 

  第3点:

  

function useWith(){
var obj = {
item:{
//姑且把这个对象叫做 this1
key:1
}
};

with( obj.item ){

obj.item
= {
key :
2
};

console.log( key );
//1, 你悲剧的访问到了1
//理由:with 已经确定了当前 this 指向了 this1,
//在访问 key 的时候不会重新读取 obj.item 新的指针。
//疑问:本来在 obj.item 被重新赋值的时候就应该把 this1 的这个对象抛弃了(它已经没有存在引用了),那么最后一句key的访问结束内存会被回收吗?
}
}

useWith();

看到 javascript 第6版上的例子:(一个更加悲剧的with使用)

var c ={};

with(c){
x
= 111;
}

console.log(c.x);
// undefined
console.log(window.x); // 111

 

 

  第4点:

  可以想象with是帮你保存一个this指针而不用重复书写,我们当然也可以用一个变量来保存这个指针。

  故大部分with的应用场景可以有替代方案是可以做到的。

为什么做这个测试?

  只是想弄的明白些,或者接收更多人的看法。

本文链接

继续阅读 »