function g () {
var x;
function y () {};
var z;
}
我想知道上面代码在被吊起时的确切顺序。
理论1: var
和function
之间的顺序保持原样:
function g () {
var x;
function y () {};
var z;
}
理论2: var
来到function
之前:
function g () {
var x;
var z;
function y () {};
}
理论3: function
来到var
之前:
function g () {
function y () {};
var x;
var z;
}
哪种理论是正确的?
答案 0 :(得分:17)
首先提升函数,然后按ECMAScript 5, section 10.5提升变量声明,指定如何进行提升:
我们首先处理第5步处理函数声明:
对于代码中的每个FunctionDeclaration f,在源文本顺序中执行...
然后第8步处理var
声明:
对于代码中的每个VariableDeclaration和VariableDeclarationNoIn,在源文本顺序中执行...
因此,函数的优先级高于var
语句,因为后面的var
语句不能覆盖先前处理的函数声明。
(子步骤8c强制执行条件“如果varAlreadyDeclared为假,则[继续...]”因此不会覆盖现存的变量绑定。)
function f(){}
var f;
console.log(f);
var g;
function g(){}
console.log(g);
log
次调用都显示函数,而不是undefined
值。
答案 1 :(得分:1)
尽管顺序由规范确定,但正如公认的答案所指出的那样,顺序实际上并不那么重要。
var
声明被悬挂,但不初始化(如果有的话)。如果var
或其他function
声明已经使用了该名称,则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
声明无效。在这两种情况下,结果都是相同的。