2015-09-22 18 views
1

所以我正在做一個小提琴,並注意到我得到了不同的結果,一個沒有錯誤,另一個是關於取決於瀏覽器的未定義函數。爲什麼Chrome處理本地函數的作用域與Firefox不同?

在Chrome中,它功能完美,工作良好,但在Firefox中它提供了未定義的功能。

這是我使用的小提琴:

http://jsfiddle.net/98a45Lk9/ - 單擊畫布,檢查開發者工具在Chrome和Firefox瀏覽器。

對我來說,在Chrome中我得到:test 在Firefox中,我得到:ReferenceError: update is not defined

爲什麼這些瀏覽器的JavaScript的處理不同,因爲他們似乎產生不同的結果,他們必須有不同的規則?

我不知道其他瀏覽器如IE和Opera的結果。

+0

什麼'更新'應該是? – Pointy

+0

這只是一個函數,它可以在一個瀏覽器中定義任何'something',在另一個瀏覽器中定義。'我不明白這個不一致。它爲什麼會發生。 – Sir

+0

那麼如果它是未定義的,那麼它是未定義的。你期望'update'做什麼?如果標準中沒有任何內容表明在window對象上應該有'update'方法,那麼這只是瀏覽器之間的一種實現變體。 – Pointy

回答

4

的代碼使用FunctionDeclaration外頂層聲明的(見SourceElement)並因此調用瀏覽器定義的操作。

根據ECMAScript Grammar'正確'的解決方案是拋出一個SyntaxError,但由於接受構造的實現,這放寬到merely a note in the specification

NOTE Several widely used implementations of ECMAScript are known to support the use of FunctionDeclaration as a Statement. However there are significant and irreconcilable variations among the implementations in the semantics applied to such FunctionDeclarations. Because of these irreconcilable difference, the use of a FunctionDeclaration as a Statement results in code that is not reliably portable among implementations. It is recommended that ECMAScript implementations either disallow this usage of FunctionDeclaration or issue a warning when such a usage is encountered. Future editions of ECMAScript may define alternative portable means for declaring functions in a Statement context.

總結:

function f() { 
    function g() {} /* FunctionDeclaration as SourceElement - OK! */ 
} 

function f() { 
    if (x) { 
     function g() {} /* FunctionDeclaration as Statement; 
          Browser-defined behavior */ 
    } 
} 

function f() { 
    var g; 
    if (x) { 
     g = function() {} /* FunctionExpression - OK! */ 
    } 
} 

Strict Mode火狐拋出一個語法錯誤:

[In Firefox] SyntaxError: in strict mode code, functions may be declared only at top level or immediately within another function

既不瀏覽器(45),也不IE(11)遵循此可選行爲。

This prohibition isn't strict mode proper, because such function statements are an extension of basic ES5. But it is the - "Don't Pollute Strict Mode with Non-standard Declaration Forms" - recommendation of the ECMAScript committee, and [Firefox wil] implement it.

+0

啊所以我必須在頂部聲明變量,然後將函數賦值給變量。該死的,Chrome讓我走了一條亂七八糟的習慣,讓我擺脫它! – Sir

+0

@Dave取決於函數變量的正確範圍。如果它應該是一個局部變量,那麼可以在函數中的任意位置放置var。變量提升在實現中是明確定義的(所以它可以完全等價地寫成函數f(){if(x){var g = ..}}或函數f(){if( x){g = ..}; var g}',但我儘量避免在邏輯代碼周圍出現變量提升,這在技術上是一種「優先選擇」的東西 – user2864740

+0

我指的是第三個例子,通過變量'g'作用域跨越函數'f'內的所有代碼,否則函數只會在if語句的大括號內定義作用域 – Sir

相關問題