[英]Order of hoisting in JavaScript
function g () {
var x;
function y () {};
var z;
}
我想確切地知道上面的代碼在提升時變成什么順序。
理論 1: var
s 和function
s 之間的順序保持原樣:
function g () {
var x;
function y () {};
var z;
}
理論 2: var
s 出現在function
s 之前:
function g () {
var x;
var z;
function y () {};
}
理論 3: function
s 在var
s 之前:
function g () {
function y () {};
var x;
var z;
}
哪個理論是正確的?
函數首先被提升,然后是變量聲明,根據ECMAScript 5 的 10.5 節,它指定了提升是如何發生的:
我們首先有第 5 步處理函數聲明:
對於代碼中的每個 FunctionDeclaration f,按源文本順序執行...
然后第 8 步處理var
聲明:
對於代碼中的每個 VariableDeclaration 和 VariableDeclarationNoIn d,按源文本順序執行...
因此,函數的優先級高於var
語句,因為后面的var
語句不能覆蓋先前處理的函數聲明。 (子步驟 8c 強制執行條件“如果 varAlreadyDeclared 為 false,則 [continue...]”因此現存的變量綁定不會被覆蓋。)
您還可以通過實驗看到這一點:
function f(){} var f; console.log(f); var g; function g(){} console.log(g);
兩個log
調用都顯示了函數,而不是undefined
值。
盡管該順序是由規范確定的,但正如公認的答案所指出的那樣,該順序實際上並不那么重要。
var
聲明會被提升,但不會被提升(如果有的話)。 如果名稱已被function
或其他var
聲明采用,則var
聲明無效。function
定義被提升——不僅聲明名稱,還聲明它們的值,即函數。所以下面兩段代碼:
(function () { console.log(typeof a); var a = 1; function a() { } })();
和:
(function () { console.log(typeof a); function a() { } var a = 1; })();
... 翻譯成:
(function () { function a() { } var a; console.log(typeof a); a = 1; })();
和分別:
(function () { var a; function a() { } console.log(typeof a); a = 1; })();
后兩者其實是一回事。 如果引擎首先處理提升的var
聲明,那么a
首先是undefined
,然后立即被覆蓋為函數。 另一方面,如果首先處理function
定義,則var
聲明無效。 在這兩種情況下,結果是相同的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.