浅谈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),  // 即AOB: <Func>},G: {A: <Func>window: G,Math: <any>}
    }
    
  • 外边是一个栈的形式,如果A函数中找不到变量的话,会沿着scoped找到Global的AO对象,然后进行查询所需要的变量。

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

  • 接下来就是执行B函数

    {B: {[scoped]: VO(A), // 即AOb: 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的实例。

浅谈js执行的AO/VO相关推荐

  1. 浅谈JS中常见的问题(三)

    往期文章目录 浅谈JS中常见的问题(一) 浅谈JS中常见的问题(二) JS知识总结 往期文章目录 前言 11. 同步和异步的区别 12. JS 判断变量类型的几种方法 13. 如何阻止事件冒泡与默认事 ...

  2. java执行jar中的main_浅谈java 执行jar包中的main方法

    浅谈java 执行jar包中的main方法 通过 OneJar 或 Maven 打包后 jar 文件,用命令: java -jar ****.jar 执行后总是运行指定的主方法,如果 jar 中有多个 ...

  3. 浅谈 js 数字格式类型

    原文:浅谈 js 数字格式类型 很多人也许只知道 123,123.456,0xff 之类的数字格式. 其实 js 格式还有很多数字格式类型,比如 1., .1 这样的,也有 .1e2 这样的. 可能有 ...

  4. php字面量,浅谈js之字面量、对象字面量的访问、关键字in的用法

    一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal) ...

  5. js执行过程(VO\GO\AO等)+闭包原理

    写这篇文章主要是由用来总结和复习的,最近在看why老师的js高级,学到了很多,以下仅为个人认知有误欢迎提出. 所有的js执行过程以v8引擎来说明. 1.v8引擎执行过程 1.1解析生成AST 首先v8 ...

  6. 浅谈js原型和原型链

    一.简述 对于javascript 对象(函数) 原型和原型链的理解,其实不那么难,简单来说,需要理解什么是原型,怎么访问原型,什么是原型链,怎么通过原型链去访问原型,就可以大概理清楚原型和原型链的基 ...

  7. js架构设计模式——由项目浅谈JS中MVVM模式

    1.    背景 最近项目原因使用了durandal.js和knockout.js,颇有受益.决定写一个比较浅显的总结. 之前一直在用SpringMVC框架写后台,前台是用JSP+JS+标签库,算是很 ...

  8. 浅谈js模块化:commons、AMD、CMD、ES6几种模块化的用法及各自的特点

    文章目录 一个页面需要引入多个js文件引发的问题: 模块化的好处: 几种常用的模块化规范 1. commonJs 2. AMD 3. ES6 4.CMD 总结 js模块化是现在比较流行的一种用法,它能 ...

  9. 由项目浅谈JS中MVVM模式

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.    背景 最近项目原因使用了durandal.js和knock ...

最新文章

  1. 第一次接觸sbt會遇到的
  2. idea中链接mysql查询_在Idea中编写Java程序连接查询Sqlite数据库
  3. golang 数组和切片
  4. 016_continue和break语句
  5. pytorch,onnx和tensorrt 的速度对比
  6. LeetCode 56. 合并区间(合并区间+排序)
  7. Linux wifi优先级高于ethernet
  8. angular指令中的scope的详解
  9. Can‘t update dev_zgd has no tracked branch
  10. c语言中1和0什么意思啊,精讲LOOKUP公式中1和0的含义,这1500字的详细解析值得收藏一份...
  11. S4 HANA CO和FI自动集成:成本中心分配分摊业务实践-KSV5/KSU5
  12. 50部必看的经典好莱坞电影
  13. 广西百强正菱集团涉非法吸存 当地银监局介入摸底银行贷款 柳州公安通告正菱集团涉非法集资
  14. ffmpeg webm 提取_使用ffmpeg将webm转换为mp4
  15. 另一只眼看软件研发效能提升,软件研发效能的“人性”与“物性”
  16. html网页表格中加超链接,用html给div加类似a标签的超链接(转)
  17. MATLAB导入txt和excel文件技巧汇总
  18. VMware安装centOS镜像
  19. 谁是中国的制造业超级城市?中国城市制造业辐射力排名:深圳、苏州、东莞、上海、宁波位居前五 | 美通社头条...
  20. 一台兼容计算机配置价格,完成一台计算机的配置。要求:1、写出配置单,包含品牌、型号和报价 2、写出配置...

热门文章

  1. [Unity] Mesh网格位置偏移
  2. EJB到底是什么,真的那么神秘吗
  3. 使用jgit第三方库拉取代码
  4. 印度英语将征服世界?
  5. 爱上一个叫史今的男人
  6. 天地人大湖北版2004-2005学年度第二学期第一次版聚总结
  7. Android Scheme 跳转
  8. Calculated padded input size per channel: (99 x 4). Kernel size: (129 x 1). Kernel size can‘t be gre
  9. abbex 区块链学院如何交易之 第十二章 反败为胜:重创之后重拾信心
  10. disruptor框架为什么不流行_从构建分布式秒杀系统聊聊Disruptor高性能队列