首页 > 其他 > 详细

关于预解析和作用域链的认识

时间:2017-02-13 13:57:27      阅读:124      评论:0      收藏:0      [点我收藏+]

作用域链

  如果一个函数需要用到一个变量,那它会先在自己的作用域里去找这个变量。如果自己有那它就直接使用自己的,如果自己没有,那它就会一层一层往外找,直到找到外面的变量,找到后就用外面的变量

  注意:作用域链会一层一层往外找,不会往里面找

  下面看两个示例

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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!