JavaScript 中的吊装顺序
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, section 10.5 指定提升如何发生:
我们首先进行第 5 步处理函数声明:
For each FunctionDeclaration f in code, in source text order do...
然后第 8 步处理 var
声明:
For each VariableDeclaration and VariableDeclarationNoIn d in code, in source text order do...
因此,函数的优先级高于 var
语句,因为后面的 var
语句不能覆盖先前处理的函数声明。
(子步骤 8c 强制执行条件 "If varAlreadyDeclared is false, then [continue...]",因此现存的变量绑定不会被覆盖。)
function f(){}
var f;
console.log(f);
var g;
function g(){}
console.log(g);
两个 log
调用都显示函数,而不是 undefined
值。
虽然 order 由规范确定,但正如已接受的答案所指出的那样,该顺序实际上并不那么重要。
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
声明无效。在这两种情况下,结果是相同的。
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, section 10.5 指定提升如何发生:
我们首先进行第 5 步处理函数声明:
For each FunctionDeclaration f in code, in source text order do...
然后第 8 步处理 var
声明:
For each VariableDeclaration and VariableDeclarationNoIn d in code, in source text order do...
因此,函数的优先级高于 var
语句,因为后面的 var
语句不能覆盖先前处理的函数声明。
(子步骤 8c 强制执行条件 "If varAlreadyDeclared is false, then [continue...]",因此现存的变量绑定不会被覆盖。)
function f(){}
var f;
console.log(f);
var g;
function g(){}
console.log(g);
两个 log
调用都显示函数,而不是 undefined
值。
虽然 order 由规范确定,但正如已接受的答案所指出的那样,该顺序实际上并不那么重要。
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
声明无效。在这两种情况下,结果是相同的。