zoukankan      html  css  js  c++  java
  • 分享-结合demo讲解JS引擎工作原理

    代码如下:

    var x = 1;
    function A(y){
       var x = 2;
       function B(z){
          console.log(x+y+z);
       }
       return B;
    }
    var C = A(1);
    C(1); 

    分析如下:

          阶段一:全局初始化阶段

          js引擎在进入一段可执行代码时,要完成以下三个初始化工作:

    1. 创建一个全局对象
    2. 构建一个执行环境栈,与此同时创建一个全局执行环境并压入执行环境栈中
    3. 创建一个与全局执行环境相关的变量对象,此变量对象不仅包含全局对象中的所有属性,还包含全局定义的变量x和函数A。

          阶段二:执行函数A

          当执行函数A(1)时,js引擎要完成以下三个工作:

    1. 创建函数A的执行环境,并将A的执行环境推入执行环境栈顶并获取执行权限。
    2. 创建函数A的作用域链,js中每个函数执行时都会创建自己的执行环境,每个执行环境都有自己的作用域链,当执行环境被创建时,其作用域链初始化为当前函数的scope所包含的对象,即当前函数的作用域对象,而函数的scope是在函数定义时确定的,初始化为函数定义时所处环境的变量对象。
    3. 创建函数A执行环境的变量对象(也叫活动对象),此对象包含函数的形参、arguments对象、this对象以及内部变量和内部函数的定义,然后将此变量对象推入函数A作用域链顶端。 

           阶段三:执行函数B 

           函数A被执行以后,返回了B的引用,并赋值给了变量C,执行 C(1) 就相当于执行B(1),JS引擎需要完成以下工作:

    1.  创建函数B的执行环境,并将B的执行环境推入执行环境栈顶并获取执行权限。(注意:当函数A返回后,A的执行环境就会从栈中被删除,只留下全局执行环境)
    2. 创建函数B的作用域链,函数B是在函数A中定义的,函数B的作用域链初始化为执行环境A的变量对象。
    3. 创建函数B执行环境的变量对象(活动对象),并将此变量对象推入函数B作用域链的顶端。

          

      当函数B执行“x+y+z”时,需要对x、y、z 三个标识符进行一一解析,解析过程遵守变量查找规则:先查找自己的变量对象(活动对象)中是否存在该属性,如果存在,则停止查找并返回;如果不存在,继续沿着其作用域链从顶端依次查找,直到找到为止,如果整个作用域链上都未找到该变量,则返回“undefined”。

           函数B的作用域链为:

           B的变量对象----->A的变量对象----->全局变量对象

           因此,变量x会在A的变量对象中找到,y也会在A的变量对象中找到,z在自己的变量对象中找到 ,结果为2+ 1+ 1 = 4;

           总结:

    1. 函数的scope是在定义时确定的。
    2. 函数的作用域链是在执行时确定的。
    3. 函数执行时首先会创建执行环境,然后创建函数的作用域链,接着创建函数的活动对象。          

         

          参考博客地址:http://www.cnblogs.com/onepixel/p/5090799.html(强烈推荐)

          

  • 相关阅读:
    Python_反射
    Python_面向对象_类2
    Python_面向对象_类1
    Python_logging模块
    Python_子进程管理subprocess模块
    Python_python内置加密模块
    Python_configparser模块
    Python_xml
    Python_shelve模块
    Python_shutil模块
  • 原文地址:https://www.cnblogs.com/zifayin/p/10725356.html
Copyright © 2011-2022 走看看