作用域链
如果一个函数需要用到一个变量,那它会先在自己的作用域里去找这个变量。如果自己有那它就直接使用自己的,如果自己没有,那它就会一层一层往外找,直到找到外面的变量,找到后就用外面的变量
注意:作用域链会一层一层往外找,不会往里面找
下面看两个示例
1 var a=12; 2 function fn(){ 3 console.log(a); //12 函数先会在自己的作用域里去找a,发现没找到,它就会找它父级,在父级身上找了到一个a,那它就用这个a 4 } 5 fn();
1 function fn2(){ 2 var a=20; 3 console.log(a); //20 函数在自己的作用域里找到了一个变量a,那它就不会再去找外面的a 4 } 5 fn2();
预解析
函数或者变量都会有一个提解析的过程,js会把函数或者变量提前解析一下,解析到它们对应的作用域最开始的值
预解析的4个步骤如下,不管什么情况下,都是按照这4个步骤执行预解析的
1、先找var 、function关键字以及参数
2、如果找到了var(声明的变量,参数),会给他赋一个undefined。如果找到了function,那它会把整个函数都拿过来
3、把找到的东西,放到对应的作用域的最开始的位置
4、逐行执行代码
下面分析一下一个示例的预解析步骤
1 var b=12; 2function fn(){ 3 console.log(b); 4 var b=20; 5 console.log(b); 6 } 7 fn(); 8 console.log(b);
上面示例总共8行,按照预解析步骤逐一执行如下:
先找var、function,即1-6行代码,把b赋值为undefined,把var b=undefined和函数拿到页面作用域开始的地方,即第1行之前,然后逐行执行代码;
然后往下走,走到第7行,调用函数,然后执行第2行的函数,在函数内再次按照预解析步骤执行,先找var、function,找到var b=20,没有找到函数,然后给b赋值undefined,即var b=undefined放到函数作用域开始的地方,即第3行之前,然后逐行执行函数内代码;
执行第3行时,找到第3行赋的值undefined,所以第3行结果为undefined;
执行第4行时,var b=20会把第3行前的var b=undefined覆盖;
执行第5行时,结果是第4行的赋值的20;
第7行的函数调用执行完毕;
第8行的b,会在自己的作用域内找b,第1行之前找到var b=undefined,第1行的var b=12会把undefined覆盖,所以执行结果为12。
注意:1、函数内的赋值没有声明的情况下,比如b=10,如果函数内没有找到变量b的声明,此赋值为全局变量的赋值,会找函数外的调用函数前的变量,找到的话会把调用函数前的变量的值覆盖,没找到的话相当于在调用函数处声明了一个变量var b=10
2、函数有参数的话相当于在函数开始执行时声明了变量为undefined
3、函数外声明的变量没有被覆盖的话,是不受函数内变量影响的
函数预解析和作用域链结合的示例分析
1 var c=10; 2function fn1(){ 3 console.log(c); //10,通过作用域链找到函数外的变量var c=10 4 c=20; //作用域内没有声明c,c=20把函数外面的var c=10覆盖,执行位置是函数调用的位置 5 } 6 fn1(); 7 console.log(c); //20,在第6行函数调用处找到20
1 var d=12; 2function fn2(d){ //此行的参数相当于在函数内第3行前声明了一个d,值为undefined 3 console.log(d); //在第3行前找到值undefined 4 d=24; //值赋给函数内声明的undefined 5 } 6 fn2(); 7 console.log(d); //12,在第1行找到自己作用域内的值12
1 var e=13; 2function fn3(e){ //传的参数是在函数内第3行前声明了var e=undefined 3 var e=13; //把作用域内第3行前的var e=undefined覆盖 4 console.log(e); //13,第3行找到作用域内的值13 5 e=54; //函数内找到e的声明,把var e=13覆盖 6 console.log(e); //54,第5行找到作用域内的54 7 } 8 fn3(e); 9 console.log(e); //13,第1行找到自己作用域内(函数外部)的13
此类题目经常出现倒面试题目中,只需按照预解析4个步骤逐行执行即可。
如有纰漏,欢迎指正!
原文:http://www.cnblogs.com/suyingwei/p/6393360.html