变量声明提升 和 函数声明提升

变量提升:

  在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域。变量提升即将变量声明提升到它所在作用域的最开始的部分,举个例子如:

console.log(a); //undefined
var a = 1;

function foo(){
  console.log(a)// undefined
  var a = 2;
  console.log(a);// 2      
}

foo();

console.log(a)// 1

之所以会是以上的打印结果,是由于js的变量提升,实际上上面的代码是按照以下来执行的:

var a; // 变量提升,全局作用域范围内
console.log(a);//此时只是声明,并没有赋值 所以为undefined
a = 1; // 此时才赋值为1

function foo(){
 var a ;// 变量提升,函数作用域内
 console.log(a);////此时只是声明,并没有赋值 所以为undefined
 a = 2; // 此时赋值为2
console.log(a)//2
}

foo();
console.log(a)//输出全局变量a,所以为1

函数提升:

  函数声明存在提升

foo(); //1
function foo(){
  return 1;   
}

  但函数表达式不存在提升。

foo();//foo is not function
var foo = function(){ //此时的匿名函数不存在提升,就相当于正常的变量赋值。
 return 1;
}

 函数声明提升优先级高于变量声明提升(如果函数名和变量名相同,则函数声明会覆盖变量声明,但不会覆盖变量赋值)

  函数声明提升优先级高于变量声明提升:

function foo(){
 
}
var foo;
alert(typeof foo) //function

尽管变量声明在下面,但输出的类型仍是function。也就是说函数的优先级高于变量声明。

但是如果变量赋值了,那变量赋值初始化就覆盖了函数声明。看下面的例子:

function foo (){
    return 1;
}
var foo = 1;
alert(typeof foo) //number

上面的代码等价于:

function foo (){
    return 1;
}
var foo;
foo = 1;
alert(typeof foo) //number

之前面试遇到的题目

var a = 1;
function foo (){
    a = 2;
    return ;
    function a(){
        return 3;
    }
}
foo();
console.log(a) // 1

最后输出的a 为1。 这题涉及到了函数声明提升。相当于如下执行顺序:

var a = 1;
function foo (){
    function a(){ //函数声明被提升了
        return 3;
    }
    a = 2; //此时的a为局部变量
    return ;
}
foo();
console.log(a) // 1
原文地址:https://www.cnblogs.com/yangkangkang/p/7810086.html