FireFox和FireBug的一個BUG

來源:互聯網
上載者:User

 

  前幾日,和朋友解說javascript預解析機制的時候,給了下面的範例程式碼:

 

 

var a = 1; 

function a(){ 

  alert(1111); 

}; 

 

alert(a); 

 

毫無疑問,結果應該是彈出1,簡單的說,瀏覽器在執行JS代碼時,第一步先掃描碼塊,遇到var關鍵字,則提前至當前範圍的程式碼的開頭,接著掃描function聲明,接在var之後,然後執行代碼,於是上述代碼真正執行時應是這樣的:

 

var a ; 

function a(){ 

  alert(1111); 

}; 

a = 1; 

alert(a); 

如果有疑問的同學可以參考ECMA文檔,下面這個連結我網上搜的,不想去求證,只想理解機制的同學可以參考下:http://www.zhufengpeixun.com/jishujiangtang/javascriptjiangtang/2011-01-16/512.html 

 

   

 

       第一部分的代碼,在FF、chrome、IE下運行都是顯示1,沒啥疑問,而我朋友在FireBug console下啟動並執行時候,確彈出函數代碼,也就是:

 

function a(){

  alert(1111);

};

 

隱約記得半年前在網上看到一個老外的文章說FireBug console是用eval執行輸入的代碼的,不過具體忘記了,最近去搜也沒搜到。在這裡個人推測下,FireBug是按語句一條一條eval的, 也就是上面代碼變為:

 

 

eval('var a = 1'); 

eval('function a(){alert(1111);}'); 

eval('alert(a)'); 

而eval是將執行的語句加入到最近範圍中,按上述的方式,每條語句都是立即執行,自然就是彈出函數代碼了。自此,FireBug的解析問題也許有一個推測的答案,希望有更權威的文獻論證。

 

 

-------------------------------------------------華麗分割線-----------------------------------------------------------------

 

       接著是FireFox下的Bug,同樣是類似的代碼,今天不知腦抽怎麼的,居然會用這樣的代碼去測試,居然會測試出FF和IE8以及Chrome的不同執行結果,先不廢話,代碼如下:

 

 

  var a = 1; 

  function a(){ 

    alert(1111); 

  } 

   

  alert(a); 

是的,你沒看錯,只是在最開始的代碼上加入了兩個大括弧而已,JS是函數級範圍,以上從文法角度說,依然是在全域下運行,依然是應該彈出1,在Chrome14和IE8下運行也是如此,可是在FireFox6下運行,居然彈出的是函數代碼,坑爹啊是不,彈出的是函數代碼啊。。 蛋都碎了。。 這又是個什麼情況?

  推測1: 難道FireFox的JS引擎對花括弧內的語句是一條一條解析的,而沒有經過預解析過程?以下代碼似乎推翻了這個推測:

 

 

if(0){ 

  var a = 1;     

  function a(){ 

    alert(1111); 

  } 

  alert(a); 

 

alert(a) 

 

上述代碼在FF下,彈出的是undefined,說明a還是被預解析了,如果沒有預解析,應該是報錯的。

上述代碼在chrome和IE8下,彈出的是函數代碼,說明什麼了?  不是太理解? 再加句,執行以下代碼:

 

 

if(0){ 

  var a = 1;     

  function a(){ 

    alert(1111); 

  } 

  alert(a); 

 

alert(a) 

a(); 

 

以上代碼在FF下執行,先彈出undefined,接著報錯,提示a() is not a function;在IE8和Chrome下運行,彈出函數代碼,以及1111,說明a()這個語句正常執行了。說明Chrome和IE8都掃描了var和function聲明,但是因為if中的條件為假,所以a=1不會被執行,最終a是個function。 莫非FF把花括弧內的函式宣告當作函數運算式?這樣的話確實不會預解析了。

於是有了推測2:

 

       FF對JS語句的var關鍵字和其他瀏覽器一樣,都是優先掃描,但是對語句塊(花括弧)內的function聲明有著不同的處理,IE8和Chrome對語句塊內的function聲明同樣是預解析處理, 而FF對語句塊內的function聲明則當作函數運算式,即上述代碼中的函式宣告在FF中翻譯為:var a  = function(){alert(1111);}; 這樣做似乎可以對JS進行最佳化,比如上述的if語句,條件為假,內部代碼理應不被執行,而在IE8和Chrome下確發現a居然是個函數,對未理解JS預解析機制的同學會造成莫大的迷惑。

 

 

      至此,似乎FireFox下的Bug也有了一個似乎合理的解釋。不過同樣的,這兩個解釋都是推測,還是希望有權威的資料出來。

 

摘自 Exodia的專欄

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.