1.先把变量声明和函数声明提升到作用域的顶部
2.在同一个作用域下,同名的函数提升会覆盖变量提升,不管二者谁先声明
3.就算声明语句不会执行,也要先进行变量提升
变量提升的执行顺序
var a=100;
function a(){}
console.log(a)
//相当于执行:
先把变量提升剪切上去
var a;
function a(){};
a=100;
console.log(a)
var a=100;
var a=function(){console.log(1)}
function a(){console.log(2)}
console.log(a) // function (){console.log(1)}
//相当于执行:
先把变量提升剪切上去
var a;
var a;
function a(){console.log(2)};
a=100
a=function(){console.log(1)}
console.log(a)
两个同名的声明,函数会覆盖普通声明(不管二者的声明顺序)
function a(){}
var a
console.log(a) // function a(){}
/*var f = function () {
console.log('1');
}
function f() {
console.log('2');
}
f()*/
/*function f() {
console.log('2');
}
var f = function () {
console.log('1');
}
f()*/
f()
function f() {
console.log('2');
}
var f = function () {
console.log('1');
}
if语句中的变量提升
根据ECMAScript的规范,不得在非函数的代码块中声明函数,最常见的情况就是if和try语句 (但尽管这样做了,浏览器往往不报错)
if语句中的普通变量声明
/*var foo = 1;
function bar() {
if (!foo) { //由于存在函数内的变量提升,因此覆盖了全局变量下的foo,此时foo为undefined
var foo = 10; //先变量提升foo,不管foo是否会执行
}
alert(foo);
}
bar();*/
var a=2;
function fn(){
var b=0;
if(b===1){
var a=3 //不管该语句会不会执行,都要先执行变量提升
}
console.log(a)
}
fn()
if语句中的函数声明:
function fn() {
var a=2;
if (a === 1) {
function b(){}
}
console.log(b)
}
fn() undefined //如果if语句不会执行,里面的变量也存在变量提升,函数声明提升为undefined
function functions(flag) {
if (flag) {
var a
} else {
function a() { }
}
console.log(a)
}
functions(true) //undefined
function functions(flag) {
if (flag) {
function a(){console.log(1)}
} else {
function a() {console.log(2)}
}
a()
}
functions(true) // 不会执行语句的变量提升覆盖不了会执行的声明