为什么不使用 javascript with?
众所周知大家对 with 都没什么好感,而且不推荐使用。
可以收集到的理由有:
下面几条来自 《javascript权威指南》 第 5 版本。
1:使用with的语句很难优化。
2:使用with语句速度要比不使用with语句的等价代码的速度慢得多。
3:在with语句中的函数定义和变量初始化可能产生令人惊讶,和直觉相抵触的行为。
4:90%(或者更高比例)的with应用场景都可以用其他更好的方式代替。
如何证明以上观点。
第1点:貌似没有什么好的代码实例。(欢迎大家提供)
第2点:使用with语句速度要比不使用with语句的等价代码的速度慢得多。
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点:在with语句中的函数定义和变量初始化可能产生令人惊讶,和直觉相抵触的行为。
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点:90%(或者更高比例)的with应用场景都可以用其他更好的方式代替。
可以想象with是帮你保存一个this指针而不用重复书写,我们当然也可以用一个变量来保存这个指针。
故大部分with的应用场景可以有替代方案是可以做到的。
为什么做这个测试?
只是想弄的明白些,或者接收更多人的看法。