javascript使用的是函数级作用域,而不是块级作用域,并且有声明提升(hoisting)的过程。
具体来说,就是解析器在向执行过程中加载数据时,会率先读取变量或者函数声明,并且是在一开始就读取,而表达式则会在执行到所在的代码行时才会被真正解释执行。
这里具体分为两类,一种是变量声明提升,一种是函数声明提升。
关于变量声明提升:
1. 提升的仅仅是声明,例如var a=1;仅仅提升var a;的部分,也即是在这一行之前使用a的话结果会是undefined。
console.log(a);
var a=1;
//结果为undefined复制代码
2.即使在控制语句中,也会被提升。
if (false) {
var a = 2;
}
console.log(a); //undefined
复制代码
关于函数提升声明:
1.仅仅只有函数声明可以被提升,等价的函数表达式也不行。
console.log(sum(10,5));
function sum(num1,num2){
return num1+num2;
}
//会显示15
console.log(sum(10,5));
var sum = function(num1,num2){
return num1+num2;
};
//会显示Uncaught TypeError: sum is not a function
//并且如果console.log(sum)会显示undefined复制代码
2.根据Gary郭伟涵这篇文章,在控制语句中的函数声明不会被提升,原因不明。
我的证明:
console.log(sum(10,5));
if(false){
function sum(num1,num2){
return num1+num2;
}
}
//答案是Uncaught TypeError: sum is not a function,但是根据函数声明提升过程,答案应该是15才对。复制代码
同时有函数声明提升和变量声明提升时:
1.优先输出函数声明,且顺序无影响。
console.log(sum);
var sum=5;
function sum(){return 2;}
//答案是ƒ sum(){return 2;},且更换变量声明和函数声明的顺序,结果也一样。复制代码
2.同时有两个同名函数的声明,输出的是后面的一个。
*ECMAScript里面没有函数重载的概念,而是直接覆盖了。
console.log(sum());
function sum(){return 2;}
function sum(){return 5;}
//答案是5.复制代码
3.同时有两个同名变量的声明,当然答案还是undefined。