hoyong

导航

理解javascript执行环境(执行上下文)(转)

介绍三个概念

    执行环境
        全局执行环境
            在浏览器中全局执行环境就是window对象,因此所有全局变量和全局函数都是作为window对象的属性和方法创建的。
            全局环境只有当程序退出或者浏览器网页关闭后才会被销毁
        局部执行环境
            每个函数都有自己的执行环境,当js执行流进入一个函数时,函数的环境会被推入一个环境栈中,当函数执行完毕后,栈将其环境弹出,该环境即被销毁。
    变量对象(Variable object)
        简称VO, 非函数执行环境被创建时都会对应创建一个VO对象,该对象保存着当前环境中定义的所有变量和函数
    活动对象 (Activation object)
        简称AO, 函数的执行环境是在调用时创建的,在创建函数执行环境的同时会对应创建一个AO带有arguments属性的AO对象,该对象将代替VO对象来保存当前函数环境中的变量,参数,函数,所以在函数执行环境中VO就是AO

js执行流

    第一步,当程序加载时全局执行环境就被创建,并且创建一个VO对象来保存当前全局变量与全局函数,在刚刚创建的VO对象中,变量的值被保存为Undefined,函数属性的值保存为对应的函数体
    这里写图片描述

 


    第二步,当程序执行到第16行的时候,变量g执行赋值操作,VO对象中的属性g的值发生变化
    这里写图片描述

 


    第三步,当程序向下执行,遇到fn1函数,由于fn1函数没有被调用,所以程序直接来到第34行,发现fn2函数被调用并传参,那么就进入fn2函数内部并创建fn2执行环境,由于在函数执行环境中,VO是无法直接访问的,所以当fn2环境被创建时,会同时创建一个AO对象,该对象默认带有一个arguments属性,这个属性保存了函数调用时传入的实参,该AO对象同时也会保存fn2函数的形参num3并赋值,保存局部变量x,x的值为Undefined,
    这里写图片描述

 


    到这里可以看出AO与VO的区别,
        非函数执行环境对应创建一个VO对象,
        函数执行环境对应创建一个默认带有arguments属性的AO对象,
        AO是函数执行环境下的VO,两者的作用是相同的

    第四步,当代码运行到第41行x被赋值,AO赋值操作与VO完全一样,所以就不画图了,代码继续向后执行,遇到fn1函数调用,并且发现fn2执行环境中没有可执行语句了,那么程序将进入fn1函数,并将fn2执行环境与fn2的AO对象销毁,程序进入fn1后执行的操作与进入fn2时的操作一样,创建fn1执行环境,并创建fn1环境下的AO对象,保存fn1执行环境下的arguments,形参,变量和函数;
    这里写图片描述

 


    第五步,当程序执行到第35行,遇到child函数调用,那么程序进入child函数中,首先创建child执行环境,然后创建对应的AO对象,由于child没有接收到任何参数,所以AO中的arguments为空数组,形参值为Undefined,b属性值在在AO初始时为Undefined,遇到赋值语句是将会改变,由于child执行环境是包含在fn1执行环境中,所以只有当child执行环境销毁之后,fn1执行环境才会销毁,最终只保留下全局执行环境,直到浏览器页面关闭全局环境才会被销毁
    这里写图片描述

 



总结

    当程序开始执行,自动创建一个全局执行环境和一个VO对象
    当函数被调用时,在函数中会创建一个函数执行环境和一个AO对象,AO与VO功能相同
    当函数执行环境被创建后,js会创建一个执行环境栈,将当前执行环境入栈,当该函数执行结束之后,其对应的执行环境会从栈中抛出,并销毁
    类似于下图
    这里写图片描述

 



参考资料

    深入理解javascript原型和闭包(13)-【作用域】和【上下文环境】
    JavaScript的执行上下文
    JavaScript高级程序设计(第3版)第四章-73页
    JavaScript高级程序设计(第3版)第七章-178页,179页
---------------------
作者:SevenBig
来源:CSDN
原文:https://blog.csdn.net/itSeven7/article/details/81260899
版权声明:本文为博主原创文章,转载请附上博文链接!

posted on 2019-04-27 16:11  hoyong  阅读(181)  评论(0编辑  收藏  举报