先来看下变量的提升规则
1.JavaScript代码在预解析阶段,会对以var声明的变量名,和function开头的语句块,进行提升操作
2.变量和函数同名
在提升的时候,如果有变量和函数同名,会忽略掉变量,只提升函数
3. 函数同名,如何提升
预处理的时候,会将两个函数全部提升,但是后面的函数会覆盖掉前面函数
如下代码
console.log(a);//undefined
var a = 123;
var num = 456;
function test(){
console.log(num);
var num = 10;
}
test();//undefined
两个打印结果均为undefined,让我们来看下实际提升后的代码
var a;
console.log(a);
a = 123
var num;
num = 456;
function test(){
var num;
console.log(num);
num = 10;
}
test();
提升后的代码可以看出,在js中执行顺序是从上往下执行,而打印语句在打印的时候会在本身所在作用域里找。而在test()函数中,打印语句调用时 有var num语句 num还没有赋值,所以打印结果为undefined。
在全局中用var 声明变量相当于把变量提升为全局变量。
var num = 456;
function f1() {
console.log(num);
num = 10;
}
f1();//打印结果为456
console.log(num);//打印结果为10
打印结果分别为456和10,让我们来看下实际提升后的代码
var num;
function f1(){
console.log(num);
num = 10;
}
num = 456;
f1();
console.log(num);
不难看出,还是那个道理JS从上往下执行代码,函数f1不调用时,不执行。当调用f1时会去自身函数作用域中找num,这是在函数作用域中并没有定义num,所以去上一作用域找,这时在全局中把num赋值为456,所以打印456,调用函数后,num赋值为10,所以再次打印出来值变成了10。
有的人可能会有疑惑,第一个例子里面调用test函数后为什么不去全局中找,是因为在test中已经用var定义了num,所以找到了num但没赋值,所以打印undefined。而在第二个例子中,f1函数中没有用var定义,所以要去全局找num。
变量的搜索原则
1.在使用变量的时候
首先在所在的作用域中查找
如果找到了 就直接使用
如果没有找到 就去上级作用域中查找
2.重复以上步骤
如果直到0级作用域链也就是全局作用域还没有找到,报错