首页 > 代码库 > 通过一个简单闭包,弄懂JS执行原理

通过一个简单闭包,弄懂JS执行原理

<script>       

    function f1()
            {
                var age = 18;

                function f2()
                {
                    alert(‘我今年:‘+age+‘岁‘);
                }

             return f2;
            }
        
        var func3 = f1();

        func3();
</script>
            闭包原理详解:----->JS的执行原理

            首先,js执行分为两步骤,预编译阶段和执行阶段,明白了这个步骤,那么就以上述例子为例来慢慢分析(先花一点时间,看看上述代码,自己理解一下,再看下面的说明,效果更佳)

            注:当我们在浏览器访问这个页面时,浏览器已经在瞬间完成了预编译和执行阶段
           

    ** 函数在声明时,会创建一个与之关联的活动对象(Active Object)也叫AO对象,AO里面包括很多东西,除了函数执行环境内的变量和函数的信息,还包括arguments对       象,scope属性,this对象等.
           

          1. 预编译阶段:
             1.1  在全局层面创建VO对象,vo对象包含全句的变量声明和函数,
            伪代码:    VO={ f1:function(){.....}}
             1.2 进入函数f1 ,创建AO对象(AO对象和VO对象的角色一样,只是叫法不一样)
               1.2.1 首先分析形参,函数没有形参,
               1.2.2 再分析变量声明 有,AO{‘age‘:‘undefined‘}
               1.2.3 再分析函数声明 有,AO{‘f2‘:‘function(){..}‘}

               此时整个VO对象为:
      VO和AO(活动对象)角色一样,只是叫法不一样,不用死扣.
               VO{
                    f1:function()
                    {AO
                            ‘age‘:‘undefined‘   
                            ‘f2‘:‘function()
                            {AO
                              scope:指向f1的AO对象   ###每个函数被声明时,都会创建一个与之关联的scope的属性
                                                     ##scope总是指向定义函数时所在的环境
                            }‘                      ##就因为有了scope,作用域链的效果才能体现出来,所以scope很伟大
                            scope:指向VO
                    }
               }

            2.执行阶段
             2.1 f1(),执行,f1执行环境的AO对象:AO{‘age‘:18};
                  f2内的AO{‘age‘:18,scope:指向f1的执行环境}

             2.2 func3(),执行,实际是在执行:f2(),而f2的AO{‘age‘:18,scope:指向f1的执行环境,alert(‘我今年:‘+age+‘岁‘)}
                所以func3() 能接受到局部变量age  因此就能打印出18.


       注:考虑到能更简单/易懂了解到闭包,所以上述代码在执行细节和执行情况做了简化,没有牵扯到太晦涩难懂的知识点(环境栈等),若想了解JS更高级的部分,推荐<Javascript权威指南>

          如果有朋友还是不太懂闭包,js执行原理,可以留言,一起探讨.

通过一个简单闭包,弄懂JS执行原理