• js 预编译 解释执行 作用域链 闭包


    <script>
         var a,
             b = 1;
         function c(x){
             var aa = 2;
             function d(){
                var ab = 3;
             }
        }
         var d = function(){
          //...
         }
         c(10);
        
    </script>

    预编译与解释执行 

    页面产生时创建全局对象window对象,同时创建document、history、 location、navigator、screen等属性。

    脚本文件加载完后,分析语法是否合法。

    开始预编译

    (1)查找变量声明,作为window属性,并且值为undefined

    (2)查找函数声明,作为window属性,值为函数体

    上面js预编译后的window对象:

    window = {
        //页面加载创建window时,添加的属性
        a: undefined,
        b: undefined,
        d: undefined,
        c: function c(x){
              var aa = 2;
              function d(){
                   var ab = 3;
               }
         }
    }

    预编译后,从上到下解释执行

    window.b = 1;

    window.d = function(){

      //...

    }

    执行c(10)

    解释执行后的window对象:

    window = {
        //页面加载创建window时,添加的属性
        a: undefined,
        b: 1,
        d: function(){//...},
        c: function c(x){
              var aa = 2;
              function d(){
                   var ab = 3;
               }
         }
    }

    作用域与闭包(函数c的创建与执行)

    在js文件预编译时,创建c函数,函数c在创建的过程中,创建了一个内部属性[[scope]],即该函数的作用域链,作用域链是作用域对象的集合。

    在执行函数c时,首先预编译处理,创建一个执行上下文对象(execute context),即一个函数运行时的环境。执行上下文对象有它自己的作用域链(scope chain)。在上下文对象创建时,初始化它的作用域链。首先把c.scope赋值给context.scope,然后创建一个活动对象(Active Object),并且把活动对象放在context作用域链的最前端。

    AO(活动对象)创建:

    (1)查找形参和变量声明,赋值为undefined

    (2)实参值传给行参

    (3)查找函数声明,赋值函数体

    在函数执行时,访问数据的权限,从作用域链从上往下查找。

    在函数c执行时,函数内部的函数d创建,在创建过程中d有一个自己的作用域链。作用域链指向的对象与c的上下文执行环境的作用域链分别指向相同的对象。

    当函数C执行完后,执行上下文对象销毁。由于AO对象被函数d的scope引用,则AO对象不能被销毁。若函数d没有被销毁(如函数d作为返回函数被全局变量引用),AO对象一直存储在内存中。

    闭包:一个函数内嵌套一个函数,嵌套的函数未被释放时,外部函数内的变量不能释放。

    如:

    function A(){

      var a = 1;

      function B(){

        var b = 2;

           }

      return B;

    }

    var b = A();

    分析:函数A执行后,由于函数内部的嵌套函数被全局变量b引用,即函数B不能被释放。又函数B的作用域链引用了函数A的AO对象,所以函数A内的变量的内存不能被回收。

      

  • 相关阅读:
    Partial Class —— 转发
    HTTP Message Handlers in ASP.NET Web API & HttpClient Message Handlers in ASP.NET Web API (转发)
    egg.js sequelize 事务处理
    (sequelize)bulkCreate函数中的updateOnDuplicate参数使用
    Sequelize 关联查询数据合并字段
    Vue获取钉钉免登陆授权码
    Microsoft太小气了,Wallop的帐号竟然被取消了。
    plot_importance多分类、排序不匹配、图片数值不显示
    Markdown常用语法说明
    UIS8910的引脚复用
  • 原文地址:https://www.cnblogs.com/fe-huahai/p/6433270.html
Copyright © 2020-2023  润新知