引擎会在解释javascript代码之前首先对其进行编译,编译阶段中的一部分就是找到所用的声明,并用合适的作用域将它们关联起来。
因此,包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。
a=2;
var a;
console.log(a); // 2
很多人会认为是undefined
var a;这个声明是在编译阶段进行的,a=2会被留在原地等待执行阶段
console.log(a)
var a=2; // undefined
只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
foo();
function foo(){
console.log(a); // undefined
var a=2;
}
foo函数的声明被提升了,foo(…)函数自身也会在内部对a进行提升
因此上面这段代码可以理解为下面这种形式
function foo(){
var a=2;
console.log(a);
}
foo();
如果声明了,没有赋初始值,不会报错,该值输出undefined。如果没有声明,会报错ReferenceError。
如果本来是变量,当作函数调用, 会报错TypeError
foo(); // TypeError: foo is not a function
var foo=function bar(){
console.log("a")
}
函数声明会提升,但是函数表达式不会
foo(); //TypeError
bar(); // ReferenceError:
var foo=function bar(){
console.log("a")
}
函数优先提升
foo();
var foo;
function foo(){
console.log(1)
}
foo=function(){
console.log(2)
}
输出1,而不是2