mar*_*aft 10 javascript hoisting
function g () {
var x;
function y () {};
var z;
}
Run Code Online (Sandbox Code Playgroud)
我想知道上面的代码在提升时的确切顺序.
理论1:var s和functions 之间的顺序保持原样:
function g () {
var x;
function y () {};
var z;
}
Run Code Online (Sandbox Code Playgroud)
理论2: var先到functions:
function g () {
var x;
var z;
function y () {};
}
Run Code Online (Sandbox Code Playgroud)
理论3: function先到vars:
function g () {
function y () {};
var x;
var z;
}
Run Code Online (Sandbox Code Playgroud)
哪种理论是正确的?
aps*_*ers 19
根据ECMAScript 5,第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);Run Code Online (Sandbox Code Playgroud)
两个log调用都显示函数,而不是undefined值.
尽管该顺序是由规范确定的,但正如公认的答案所指出的那样,该顺序实际上并不那么重要。
var声明会被提升,但不会被提升(如果有的话)。一个var声明是没有效果;如果名称已经采取的function或其他var声明。function 定义被提升——不仅声明名称,还声明它们的值,即函数。所以下面两段代码:
(function () {
console.log(typeof a);
var a = 1;
function a() { }
})();Run Code Online (Sandbox Code Playgroud)
和:
(function () {
console.log(typeof a);
function a() { }
var a = 1;
})();Run Code Online (Sandbox Code Playgroud)
... 翻译成:
(function () {
function a() { }
var a;
console.log(typeof a);
a = 1;
})();Run Code Online (Sandbox Code Playgroud)
和分别:
(function () {
var a;
function a() { }
console.log(typeof a);
a = 1;
})();Run Code Online (Sandbox Code Playgroud)
后两者其实是一回事。如果引擎首先处理提升的var声明,那么a首先undefined然后立即将其覆盖为函数。另一方面,如果function首先处理定义,则var声明无效。在这两种情况下,结果是相同的。
| 归档时间: |
|
| 查看次数: |
1819 次 |
| 最近记录: |