先看代码(第一个代码片段):
console.log(a); var a = 1;
如果你认为这是一段不合法的代码,在调用console.log()的时候会输出undefined,你完全正确。但是如果是下面这样呢?
a = 1; var a; console.log(a);
结果输出为1.
JavaScript会把var a=1划分为两个语句,var a和a = 1.第一个语句(也就是声明)是在编译阶段处理的,第二个语句(赋值)是在执行阶段处理的。
因此,之前的代码片段实际上是这样执行的:
var a; // -------编译阶段
a = 1; // -------执行阶段
console.log(a);
而第一个代码片段是这样执行的:
var a; // ----编译阶段
console.log(a);
a= 1; // -----执行阶段
如你所见,变量和函数声明在编译阶段被移动到了代码的顶部,这就是常说的“提升”。一定要记住,只有声明才会被提升,而赋值或者其他可执行的逻辑依然保留在原位置。
下面的代码片段展示了函数声明提升:
foo(); function foo(){ console.log(a); //undefined var a =1; }
因为函数的声明会被提升,因此我们可以在其定义之前就调用该函数。关于提升很重要的一点是,他是以作用域为单位进行的。
提升后的函数foo()会变成下面的样子:
function foo(){ var a; console.log(a); a =1; }
函数表达式并不会像函数声明那样被提升。
函数声明和变量声明都会被提升,但是函数在先,变量在后。