眾所周知大家對 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的應用場景可以有替代方案是可以做到的。
為什么做這個測試?
只是想弄的明白些,或者接收更多人的看法。