变量提升:
在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