js---作用域,作用域链,立即执行函数,闭包

作用域:

1全局作用域

全局作用域就是最外层函数定义的变量,对任何内部函数来说,都是可以访问的。

 <script type="text/javascript">
          var a = 10;
          function aa(){
           console.log(a)
           function bb(){
            console.log(a)
           }
           bb();
          }
          aa();
          console.log(a)
        </script>

2.局部作用域

局部作用域就是只在固定代码片段内可以访问到,在函数外部是无法访问的。

<script type="text/javascript">
          function aa(){
              var a=20;
          console.log(a)    
          }
          aa();
          console.log(a)
        </script>

函数外是不可以访问到函数内的,所以报错。

作用域链:

[[scope]]中所储存的执行期上下文对象的集合,这个集合成链式链接,我们把这种链式链接叫做作用域链

举例:

<script type="text/javascript">
          function a(){
              function b(){
              var b=234;    
              }
              var a=123;
            b();    
          }
          var c=100;
          a();
        </script>

1.预编译,首先创建GO

GO{

a:function a(){ }

c:undefined

}

逐行执行

GO{

a:function a(){ }

c:100

}

当函数体function a(){ }执行时预编译生一个a的AO

AO{

a:undefined

b:function b(){ }

}

逐行执行

AO{

a:123

b:function b(){ }

}

当函数体function b(){ }执行时预编译会产生一个b的AO

AO{

b:undefined

}

逐行执行:

AO{

b:234

}

此时function a(){ }的作用域链是

                                       第0位:a的AO

                                       第1位:GO

function a(  ) {  } 的作用域链是

                                       第0位:b的AO

                                       第1位:a的AO

                                       第2位:GO

所以在执行代码时会先从自身的AO中查找,如果找不到再向父级查找,一级一级向上查找。

当函数执行完时会将与自身相连的AO砍掉,也就是作用域链中的第0位

3.即执行函数

针对初始化功能的函数

形式:(function( ){ } ( ) );    w3c 建议第一种

           (function( ){ }  ) ( );

        只有表达式才能被执行

        只执行一遍就自动销毁

4闭包

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏

例子:

function test(){
            var a=10
            function  arr() {
                console.log(a)
            }
            return arr;
            }
            var myArr = test();
            myArr();

预编译首先创建GO:

GO{

myArr=undefined;

test:function test() { };

}

当函数test()执行时预编译会产生一个AO
AO{

a:undefine;

arr:undefine;

}

逐行执行

AO{

a:10

arr:function arr() { }

}

当执行到function arr() { }时此时该函数体尚未执行,也就没有产生自己的AO,他的函数链就只能站在test()的作用域链上

这个时候的arr的作用域链是

                     第0位:AO   test()的

                     第1位:GO

注意:当函数体arr被返回出去的时候执行完毕,此时test会将与自身相连的AO砍掉,也就是作用域链中的第0位,但此时函数体arr是已经被返回出去了的,所以他的作用域链是不受影响的

arr执行时会产生一个AO,此时arr作用域链是

                     第0位:AO  arr的

                     第1位:AO   test()的

                     第2位:GO

从自身的AO向父级查找,直到找到需要的值为止;

 

原文地址:https://www.cnblogs.com/xuhanghang/p/10147306.html