[英]Javascript Hoisting in Chrome And Firefox
在Chrome和Firefox中運行此功能會給出不同的答案:
(function() {
if(true) {
function f() { alert("yes"); };
} else {
function f() { alert("no"); };
}
f();
})();
在Chrome中,結果是'不'在Firefox中,結果為'是'
為什么不同?
在條件語句中聲明函數是非標准的,所以不要這樣做 。 這是一個眾所周知的問題。 您可以使用函數表達式而不是聲明:
var f;
if(true) {
f = function() { alert("yes"); };
} else {
f = function() { alert("no"); };
}
f();
關於函數表達式的着名Kangax文章提供了一些額外的細節:
FunctionDeclarations只允許出現在Program或FunctionBody中 。 從語法上講,它們不能出現在Block
({ ... })
- 例如if
,while
或for
語句。 這是因為塊只能包含聲明 ,不是SourceElements,這FunctionDeclaration是。
同一篇文章還說:
值得一提的是,根據規范,允許實現引入語法擴展 (參見第16節),但仍然完全符合要求。 這正是現在這么多客戶所發生的事情。 其中一些將塊中的函數聲明解釋為任何其他函數聲明 - 只需將它們提升到封閉范圍的頂部; 其他 - 引入不同的語義並遵循稍微復雜的規則。
來自V8(Chrome JavaScript引擎) 錯誤跟蹤器 :
不是錯誤。 Firefox是唯一能夠滿足您期望的瀏覽器。
Safari和IE的行為與Chrome的/ V8相同。
這是因為Firefox缺乏功能提升,正如ECMAScript 5中所設想的那樣。
Chrome在運行函數體之前正確地為f()賦值,因此f()的第一個版本被第二個版本覆蓋。
SpiderMonkey(Firefox的JavaScript引擎)運行代碼而不預先為f()賦值,因此它使用在其路上遇到的唯一值: function f() { alert("yes"); };
function f() { alert("yes"); };
什么功能吊裝?
JavaScript的函數范圍意味着函數內聲明的所有變量在函數體中都是可見的。 奇怪的是,這意味着變量在聲明之前甚至可見。 JavaScript的這個特性被非正式地稱為提升:JavaScript代碼的行為就好像函數中的所有變量聲明(但不是任何相關的賦值)被“提升”到函數的頂部。
來源:
http://statichtml.com/2011/spidermonkey-function-hoisting.html
2011 - o'reilly - javascript - 權威指南第6版
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.