一个热爱技术的菜鸟...用点滴的积累铸就明日的达人

正文

  在上一篇文章中讲解了JavaScript内存模型,其中有提到执行上下文与变量对象的概念。对于JavaScript开发者来说,理解执行上下文与变量对象的基本理论知识,是理解闭包,原型链的关键所在(闭包与原型链会在接下来的文章中介绍)。本篇文章就带你走进JavaScript的执行上下文与变量对象,由于本人才疏学浅,若有什么表述有误的地方,欢迎各位看官能够指点一二,在此不胜感激...

  在阅读这边文章之前,默认您已经掌握了JavaScript的基本概念、栈堆等基本数据结构以及计算机基本理论基础,如有了解欠缺,请移步相关博客后再阅读本文。

一、执行上下文

  JavaScript执行程序的时候,会首先创建一个全局的执行上下文,将其放入栈中,成为栈底。而后每次执行一个函数的时候,都会去创建一个当前函数的执行上下文,然后将其压入栈中,当函数结束或者返回的时候,再从栈中弹出当前函数的执行上下文。执行上下文其实就是函数的执行环境,与Java中的栈帧很像,但是与Java不同的是,由于JavaScript是单线程的,所以JavaScript只有一个栈,对所有的执行上下文压栈与出栈都是相对与同一个栈。

  执行上下文的生命周期包含三个部分:创建阶段、代码执行阶段,执行完毕阶段

  • 创建阶段:在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,以及确定this的指向
  • 代码执行阶段:创建完成之后,就会开始执行代码,这个时候,会完成变量赋值,函数引用,以及执行其他代码。
  • 执行完毕阶段:执行完毕之后,就会开始将执行上下文出栈,随后释放掉所占用的内存

  下面用图解的方式来描述一下执行上下文的压栈与出栈的步骤,首先先看一段程序

function method_a() {method_b();method_c();
}function method_b() {}function method_c() {method_d();
}function method_d() {}method_a();

  在开始执行程序的时候,会首先创建一个global的全局执行上下文,将其压入栈中

  随后执行method_a()的时候,会创建一个method_a的执行上下文,将其压入栈中

  而后,开始执行method_a()函数中的代码,当执行到第一行的时候,发现要执行method_b()这个函数,所以又开始创建一个method_b的执行上下文,将其压入栈中

  顺利的执行完method_b()函数代码之后,将method_b的执行环境出栈,随后继续执行method_a()函数剩下的代码,发现要执行method_c()函数,所以继续创建method_c的执行上下文,将其压入栈中

  在执行method_c()函数的时候,发现又要执行method_d()函数,所以又要创建method_d的执行上下文,随后执行完method_d()之后,将其出栈,再之后method_c出栈,method_a出栈,最后剩余global执行上下文

  至此,JavaScript中的执行上下文概念介绍完毕...

二、变量对象(VO)

  在介绍执行上下文的创建阶段的时候,有提到变量对象这个概念...本节先来重点了解一下变量对象。变量对象的创建,依次经历了以下几个过程。

  • 建立arguments对象(参数对象,当某个函数接收参数的时候,会将参数封装成arguments对象)
  • 检查当前上下文的函数声明,也就是使用function声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在的内存地址的引用。如果函数名的属性已存在,那么该属性将会被新的引用所覆盖。
  • 检查当前上下文的变量声明,对于每一个变量声明,变量对象会以变量名建立一个属性,属性值为undefined。如果变量名属性已存在,则会直接跳过,原属性值保持不变(这样是为了防止将同名的函数名覆盖)

  在上面的规则中可以看出,function声明会比var声明优先级更高一点,接下来看一个demo,借此来学习与验证一下上述命题

function method(num1, num2) {console.log(arguments);console.log(num1, num2);console.log(vara, func);console.log(func());var vara = 10;console.log(vara);function func() {return 1;}function func() {return 2;}}method(1, 2);

  输出结果如下

{ '0': 1, '1': 2 }
1 2
undefined [Function: func]
2
10

  首先输出的是arguments对象,通过与第二行输出num1,num2对比可知,argument对象是一种key-value格式的对象,其中key从0开始逐步递增,value依次对应着传入参数。

  随后根据变量声明与函数声明的规则,由于变量声明,会在执行上下文创建阶段为变量赋值undefined,而函数声明,会在执行上下文创建阶段为函数变量赋值指向该函数的引用地址。故第三行输出结果为 undefined 与 [Function:func]

  又由于代码中声明了两个func函数,为了验证是否存在函数覆盖现象,打印输出func()的结果,输出结果为2,则意味着,第二个定义的func函数,在执行上下文阶段,覆盖了一开始的func函数。

  最后给vara赋值10,随即输出vara,得到10

三、OV与AO

  在初学JavaScipt中,总会有同学对变量对象与活动对象弄混,为此解释一下这两个名词。在执行上下文建立的阶段会创建变量对象,变量对象中保存arguments,function声明的函数,var声明的变量,具体的第二节已经介绍,在此不做过多阐述。当执行上下文创建过程的结束,就开始了代码执行阶段,在此时JavaScript会将变量对象(VO)转换成活动对象(AO)。在未进入到执行阶段之前,变量对象中的属性都不能访问,但是进入执行阶段后,由于变量对象被转换成了活动对象,里面的属性就可以被访问了,随后开始执行代码。因此在第二节的例子上,其实输出的都是活动对象的属性(但变量对象与活动对象中包含的属性与值都相同,所以姑且认为是变量对象)

  再总结一下,其实变量对象与活动对象都是同一个对象,只是它们处于不同的执行上下文生命周期。

四、全局变量对象

  以浏览器为例,全局变量对象为window对象。除此之外,全局变量对象的生命周期与执行上下文一致,所以如果浏览器窗口如果不关闭的话,全局变量对象将会一直存在。

转载于:https://www.cnblogs.com/sachen/p/6664630.html

JavaScript学习系列之执行上下文与变量对象篇相关推荐

  1. 一、 函数调用栈,执行上下文及变量对象

    前言 为什么会有这篇文章? 在书籍或博客上,我们经常会看到「作用域链」.「闭包」.「变量提升」等概念,说明一个问题 -- 它们很重要. 但很多时候,对于这些概念,看的时候觉得自己已经明白了,可过不了多 ...

  2. 深入理解JavaScript系列(12):变量对象(Variable Object)

    介绍 JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,可是解释器是怎样而且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候到底发生了什么? 原始公布:Dmitry ...

  3. 以及其任何超类对此上下文都是未知的_浏览器原理系列 - JS执行上下文详解(一):作用域

    本文主要介绍JS执行上下文相关的内容,理解了JavaScript的执行上下文才能更好地理解JavaScript语言本身以及该语言一些特性,如变量提升.作用域和闭包. 一.作用域 1.1 作用域 作用域 ...

  4. 大话javascript 2期:执行上下文与执行上下文栈

    一.什么是执行上下文? 执行上下文(Execution Context): 函数执行前进行的准备工作(也称执行上下文环境) JavaScript在执行一个"代码段"之前,即解析(预 ...

  5. 犀牛书第七版学习笔记:执行上下文与作用域

    目录 1.执行上下文 2.作用域链 3.作用域链增强Scope Chain Augmentation 4.变量声明 Variable Declaration 4.1使用 var 的函数作用域声明 Fu ...

  6. JavaScript学习(八十四)—变量

    JavaScript学习(八十四)-变量 一.什么是变量? 白话: 变量就是一个装东西的盒子 通俗:变量是用于存放数据的容器. 我们通过 变量名 获取数据,甚至数据可以修改. 二.变量在内存中的存储 ...

  7. java函数ao活动对象_JavaScript中的执行上下文和变量对象

    执行上下文(Execution Context) JavaScript代码执行的过程,包括编译和执行两个阶段,编译就是通过词法分析,构建抽象抽象语法树,并编译成机器识别的指令,在JavaScript代 ...

  8. 深入理解javascript内部原理(2): 变量对象(Variable object)

    本文是翻译Dmitry Soshnikov 的文章 Variable object 文章地址:http://dmitrysoshnikov.com/ecmascript/chapter-2-varia ...

  9. 串讲-解释篇:作用域,作用域链,执行环境,变量对象,活动对象,闭包

    这篇接:理论篇:作用域,作用域链,执行环境,变量对象,活动对象,闭包 看例子: function compare(value1, value2) {if (value1 < value2) {r ...

最新文章

  1. CentOS 7 安装 GlusterFS
  2. 理解oracle的共享连接和专用连接
  3. linux 解析pdf下载工具,Linux高级系统级性能分析工具-perf.pdf
  4. 文件到集合改进版【应用】
  5. Extjs grid 设置行字体颜色
  6. 行为设计模式 - 状态设计模式
  7. 百度地图切割算法讲解
  8. DropDownList 数据绑定
  9. 普林斯顿微积分读本05第四章--求解多项式的极限问题
  10. java如何编写屏幕保护程序_屏幕保护程序的编写
  11. 个人博客定制 to 鼠标单击事件绑定
  12. 基于FME实现地铁路径规划
  13. Citrix实现桌面虚拟化
  14. 游戏命中判定:圆桌算法和程序实现
  15. 拆轮子之Fish动画分析
  16. springboot+nodejs+vue+Elementui高校课外学科竞赛管理系统
  17. 1123581321递归算法java_经典算法设计方法
  18. MSDC 4.3 接口规范(25)
  19. PHP7新特性-简述
  20. idea中java文件都不能运行变成橙色文件

热门文章

  1. POST方式提交乱码解决
  2. 【转载】水木算法讨论题
  3. CVPR2021 用更好的目标检测器提取视觉特征!微软提出VinVL,基于更好的视觉特征,达到更强的多模态性能...
  4. 字节跳动智能创作实验室-图像团队2022秋招正式批开启
  5. CVPR 2021 论文/代码分类汇总!持续更新中!
  6. 度假式办公环境、值得拥有!珠海金山软件诚聘CV、C++、后端工程师
  7. 天池又上工业视觉检测算法大赛:瓶装白酒疵品质检
  8. Python最差实践
  9. 0基础学Python,要报班吗?
  10. 哈佛开源 | 从零开始教你计算机图形学