FireFox中JS引擎對函數聲明式的解析與其他瀏覽器的差異 – Javascript教程_JS教程_技術文章 – 程式設計聯盟

 

  在FireFox和FireBug中的一個Bug這篇文章中,偶然發現瞭FireFox下的函數聲明問題,一直沒有得到權威的資料來解決。11月26日面試新浪微博的時候,面試官也問到瞭這個問題,當然他沒看我的BLOG,並從他口中得知,這個不是BUG,而是FF的Monkey引擎就是這樣解析的,當然我的回答是:“個人推測,在FF下對語句快內的函數聲明轉化為函數表達式”。 面試官說不是,當然也沒給出具體答案,提示我說MDN有這方面的資料。

 

       如果懶得看前面的文章的話,可以看看下面一個簡單的例子,在FF/IE/Chrome都跑一遍,看看FF和其他二者之間的差異:(FF會報錯,其他的會彈出函數代碼)

 

view plain

if(0){ 

    function a(){} 

alert(a); 

       當天晚上,我去找瞭找MDN,還真被我找到瞭,從資料上看,和我的推測是一致的,就是例子也和我前面提到的文章也類似。具體鏈接如下:

 

https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope#Function_constructor_vs._function_declaration_vs._function_expression

 

英文水平不是特別好,這裡貼下重點部分和例子,並稍微翻譯下(強烈建議看原文,我的翻譯太蹩腳瞭):

 

 

函數聲明式非常容易(並且常常出乎意料)轉化為函數表達式。一個函數聲明要麼轉化為一個表達式的部分,要麼不再是一個函數或腳本本身的"source element"。"source element" 是腳本中或一個函數體內的非嵌套語句。

 

給出的例子如下:

 

var x = 0;               // source element 

if (x == 0) {            // source element 

   x = 10;               // not a source element 

   function boo() {}     // not a source element 

function foo() {         // source element 

   var y = 20;           // source element 

   function bar() {}     // source element 

   while (y == 10) {     // source element 

      function blah() {} // not a source element 

      y++;               // not a source element 

   } 

Examples:

 

 

// function declaration 

function foo() {} 

 

// function expression 

(function bar() {}) 

 

// function expression 

x = function hello() {} 

 

if (x) { 

   // function expression 

   function world() {} 

 

// function declaration 

function a() { 

   // function declaration 

   function b() {} 

   if (0) { 

      // function expression 

      function c() {} 

   } 

 條件定義一個函數

 函數可以用//函數語句//(一個ECMA-262 第3版允許的擴展)或者Function構造函數條件的定義。

 

 在下面的腳本中,zero函數絕不會被定義並且不能夠被觸發,因為'if (0)'將它的條件判斷為false:

 

 

 

if (0) { 

   function zero() { 

      document.writeln("This is zero."); 

   } 

如果腳本改變條件為‘if (1)’,那麼函數zero就被定義瞭。

註意:雖然這類函數看起來像函數聲明,它實質上是一個語句,因為它被嵌套在另一個語句中。見函數聲明和函數表達式的不同之處。

 

註意:一些JavaScript引擎,不包括SpiderMonkey(FF的JS引擎),不正確的將任何函數具名表達式當作函數聲明。這將導致zero被定義,甚至條件總是假的時候。條件的定義函數的一個安全做法是定義匿名函數並將其分配給一個變量(譯者註:其實就是用函數表達式):

 

 

if (0) { 

   var zero = function() { 

      document.writeln("This is zero."); 

   } 

總結

 

          MDN是很有價值的資料,有時間的話還真是需要去看看。

 

摘自 Exodia的專欄

發佈留言