1. 什么是提升
对于JS引擎,无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。即所有声明(变量和函数)都会被“移动”到各自作用域的最顶端,该过程称为“提升”。
例如,var a = 2; 可以看做是一个声明,但实际上对于JS引擎来说,是两个单独的声明,var a 是编译阶段的任务,a = 2是执行阶段的任务。
a = 2;
var a;
console.log(a);
上面的代码真正的输出结果是2,并不是undefined。因为定义声明是在编译阶段进行的,而赋值声明是在执行阶段进行的,上述代码会以如下的形式被处理:
var a;
a = 2;
console.log(a);
2. 函数优先
由于函数声明和变量声明都会被提升,函数会先被提升,然后才是变量,并且后面的函数声明会覆盖前面的。那么下面这个例子是如何提升的?
foo();
var foo;
function foo(){
console.log(1);
}
foo = function(){
console.log(2);
};
最终结果会输出1。因为函数声明会被提升,而函数表达式不会被提升。这段代码可以理解成:
function foo(){
console.log(1);
}
foo();
foo = function(){
console.log(2);
};
结果输出1,就很好理解了。
另一个例子:
foo();
function foo(){
console.log(1);
}
var foo = function(){
console.log(2);
};
function foo(){
console.log(3);
}
最后的结果是3,后面的函数声明覆盖了前者。