当你看到 var a = 2; 时,可能会认为这是一个声明。但 JavaScript 实际上会将其看成两个
声明:var a; 和 a = 2;。第一个定义声明是在编译阶段进行的。第二个赋值声明会被留在
原地等待执行阶段。
- 引擎会在解释 JavaScript 代码之前首先对其进行编译。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。
- 包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。
场景一
使用:
foo(); // TypeError
bar(); // ReferenceError
var foo = function bar() {
// ...
};
这个代码片段经过提升后,实际上会被理解为以下形式:
var foo;
foo(); // TypeError
bar(); // ReferenceError
foo = function() {
var bar = ...self...
// ...
}
- 具名的函数表达式,名称标识符在赋值之前也无法在所在作用域中
- 具名的函数表达式,名称标识符在函数表达式内部是被声明了的
场景二:函数优先
代码:
foo(); // 1
var foo;
function foo() {
console.log( 1 );
}
foo = function() {
console.log( 2 );
};
会输出 1 而不是 2 !这个代码片段会被引擎理解为如下形式:
function foo() {
console.log( 1 );
}
foo(); // 1
foo = function() {
console.log( 2 );
};
- 函数声明和变量声明都会被提升。
- 有多个“重复”声明的代码中,函数会首先被提升,然后才是变量。
网友评论