為什么不使用 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的應用場景可以有替代方案是可以做到的。

為什么做這個測試?

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM