变量提升

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)    //   不会执行语句的变量提升覆盖不了会执行的声明

你可能感兴趣的:(变量提升)