浅谈js执行的AO/VO

浅谈AO/VO详解

首先说明一下AO和VO的含义

  • AO:Activive Object,即函数的活动对象。
  • VO:Variable Object,即变量对象。

它们的作用是帮助js引擎在引用变量的时候能够去顺利找到变量。并且它们之间的联系可以实现作用域链。

VO

在执行函数的时候,会经历执行上下文的创建和代码的执行。如下图。

在这里插入图片描述

我们会先进行上下文的创建,创建VO、通过[Scope]属性指向外层的VO来进行指向外层的AO对象,那么这样就形成了作用域链。接下来是this的指向问题。

在创建VO对象的时候,会先把所有变量的声明放到一个对象属性上,但是他们的属性为空,所以这就是变量的提升

所以简单来说。VO的作存储用就是存储变量,然后本代码或者子代码在执行的时候能够知道变量的值。并且变量定义的顺序如下:

  • 参数
  • 变量
  • 函数

AO

AO和VO的关系:

AO可以理解为VO的一个实例,也就是VO是一个构造函数,然后VO(Context) === AO,所以VO提供的是一个函数中所有变量数据的模板。

对于同一个函数分多次执行,那么里面的变量、形参和定义的函数肯定是不同的函数,所以每次执行都会产生一个AO对象,即VO是AO的一个实例,但是这个实例并不是new 出来的,而是在同一段执行代码执行的时候放进来的。

  1. VO是不能访问的(除了全局上下文的VO可以间接访问),但是可以访问AO的成员(属性)。
  2. VO和AO其实是一个东西,只是处于不同的执行上下文生命周期。AO存在于执行上下文位于执行上下文堆栈顶部(就是上边说的’当控制进入函数代码的执行上下文时’)的时期。再粗暴点,就是函数调用时,VO被激活成了AO
  3. AO通过函数的arguments属性初始化,其值是一个ArgO,包括 callee、length、arg属性。其中arg属性就相当于下标,比如第一个参数对应arg = 0。

以一个例子来说明

var a = 1;

function A() {
  function B() {
    var b;
  }
  
  B();
}

A();

在执行上面代码的时候,首先会进行全局初始化,会执行以下操作

  • 初始化环境执行栈

  • 初始化全局vo和全局ao,由于全局对象只有一个,所以vo和ao一致。

  • 当执行A函数的时候,首先会创建环境变量对象,也就是A函数的VO对象,然后初始化作用域链等

    {
      A: {
        [scoped]: VO(G),  // 即AO
        B: <Func>
      },
      G: {
        A: <Func>
        window: G,
        Math: <any>
    	}
    }
    
  • 外边是一个栈的形式,如果A函数中找不到变量的话,会沿着scoped找到Global的AO对象,然后进行查询所需要的变量。

  • 要注意到作用域链是词法作用域,跟执行调用关系无关,所以并不是随着上面的栈来进行的,而是通过词法关系来产生的。

  • 接下来就是执行B函数

    {
      B: {
        [scoped]: VO(A), // 即AO
        b: undefined
      },
      A: {
        [scoped]: VO(G),
        B: <Func>
      },
      G: {
        A: <Func>
        window: G,
        Math: <any>
    	}
    }
    
  • 为什么scoped指向的是AO而不是VO呢?

    上面我们知道VO只是一个模板,由AO实例化,里面B函数执行两遍,本身产生的AO可能不同,但是指向scoped是同一个,也就是上一次执行AO的情况。更形象的在下面

    function A() {
      let count = 0;
      return function() {
        console.log(count++);
      }
    }
    

    上面个的例子如果把A函数执行两遍,里面的count不会共享,也就是AO对象不同,所以AO就是VO的实例。

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值