在JS执行前会对代码进行预处理,把当前作用域的变量和函数提升到顶部 (全局作用域、局部作用域)。变量只提升声明,赋值依旧在实际代码所在处;函数是声明和赋值都提升,且函数提升,函数提升优先级高于变量提升。
变量提升
var testVar = 1;
console.log(testVar); //1
-------------解析完实际执行时
var testVar;
console.log(testVar); // undefined
testVar = 1;
console.log(testVar); // 1
这里是把声明、赋值分开执行,以便在当前作用域调用。
声明提升到当前作用域顶部,赋值仍在赋值代码所在处。
------------同名变量提升
console.log(a)
var a = 1
console.log(a)
var a = 2
console.log(a)
//-------------解析完顺序是这样的
var a;
var a; //忽略
console.log(a) // undfined
a = 1
console.log(a) //1
a = 2
console.log(a)//2
这是因为同名变量,声明会被提升,后边会忽略。
函数提升
函数提升,函数提升优先级高于变量提升
console.log(bar); // f bar() { console.log(123) }
console.log(bar()); // undefined
var bar = 456;
function bar() {
console.log(123); // 123
}
console.log(bar); // 456
bar = 789;
console.log(bar); // 789
console.log(bar()) // bar is not a function
-----------------解析后
函数提升,函数提升优先级高于变量提升
var bar = function() {
console.log(123)
};
// 变量提升,变量提升不会覆盖(同名)函数提升,只有变量再次赋值时,才会被覆盖
var bar;
console.log(bar);
console.log(bar());
bar = 456; // 变量赋值,覆盖同名函数
console.log(bar);
bar = 789 // 再次赋值
console.log(bar);
console.log(bar());
//---------同名函数
function a(){console.log(1)}
console.log(a)
function a(){console.log(2)}
console.log(a)
a()
//---------解析完
function a(){console.log(1)}
function a(){console.log(2)}
console.log(a)
console.log(a)
a()
// --------执行, 同名函数会被覆盖。
function a(){console.log(2)}
2
// 匿名函数赋值给变量,是按照变量提升的方式,即:
var testFun = function() {};
解析时
var testFun;
testFun = function () {};