javascript执行上下文、变量对象实例分析


Posted in Javascript onApril 25, 2020

本文实例讲述了javascript执行上下文、变量对象。分享给大家供大家参考,具体如下:

突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文、变量对象、作用域、this等语言细节。内容短小而精悍,文风直白而严谨,读完有酣畅淋漓、醍醐灌顶之感,强烈推荐!!!

原文链接:这里

本想翻译成文,原来早已有人做了,这里。真生不逢时,何其遗憾啊!

做个笔记,聊慰我心。

执行上下文 ExecutionContext

每当控制器(control)转换到ECMAScript可执行代码时,都会创建并进入到一个可执行上下文。

一段简短的句子,却包含着丰富的内容:

  • 控制器:即js引擎
  • 转换:从一段可执行代码跳转到另一段可执行代码
  • 可执行代码:全局代码、函数代码、eval代码(分别对应三种作用域)
  • 执行上下文:是一个抽象的概念,ECMA-262标准用这个概念同可执行代码(executable code)概念进行区分

执行上下文在逻辑上组成一个堆栈。堆栈底部永远都是全局上下文(global context),堆栈顶部是当前/活动的执行上下文(activeExecutionContext)。堆栈在EC类型的变量(various kingds of EC)被推入或弹出的同时被修改。

例如,我们可以定义一个数组来模拟执行上下文堆栈:

ECStack = [
 globalContext,
 <foo> functionContext
]

变量对象 VariableObject

变量对象(VO)作为执行上下文的一个属性存在,它存储下列内容:

  • 所有变量声明 (var, VariableDeclaration)
    • VO的一个属性,这个属性由变量名称和undefined值组成;如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。
  • 函数声明 (FunctionDeclaration, 缩写为FD)
    • VO的一个属性,这个属性由一个函数对象(function-object)的名称和值组成;如果变量对象已经存在相同名称的属性,则完全替换这个属性。
  • 以及函数的形参
    • VO的一个属性,这个属性由一个形式参数的名称和值组成;如果没有对应传递实际参数,那么这个属性就由形式参数的名称和undefined值组成;
VO = {
  // context data (var, FD, function arguments)
 }

当我们声明一个变量或一个函数的时候,同时还用变量的名称和值在VO里创建了一个新的属性。
例如:

var m = 30;
function test(a,b) {
 var c = 20
 function d() {}
 var e = function _e() {};
}
test(10)

当进入“test”函数的上下文时(传递参数10),AO如下:

AO(test) = {
 a: 10,
 b: undefined,
 c: undefined,
 d: <reference to FunctionDeclaration "d">
 e: undefined
};

test执行到最后时,对应此刻上下文堆栈:

ECStack = [
 globalContext: {
  VO: {
   m: 30,
   test: 
  }
 },
 test functionContext: {
  VO: {
   a: 10,
   b: undefined,
   c: 20,
   d: <reference to FunctionDeclaration "d">,
   e: <reference to FunctionDeclaration "_e">
  }
 }
]

关于变量

通常,各类文章和JavaScript相关的书籍都声称:“不管是使用var关键字(在全局上下文)还是不使用var关键字(在任何地方),都可以声明一个变量”。请记住,这绝对是谣传:任何时候,变量只能通过使用var关键字才能声明。

让我们通过下面的实例看看具体的区别吧:

alert(a); // undefined
alert(b); // "b" is not defined
 
b = 10;
var a = 20;

所有根源仍然是VO和它的修改阶段(进入上下文阶段和执行代码阶段):

VO = {
 a: undefined
};

我们可以看到,因为“b”不是一个变量,所以在这个阶段根本就没有“b”,“b”将只在执行代码阶段才会出现(但是在我们这个例子里,还没有到那就已经出错了)。

让我们改变一下例子代码:

alert(a); // undefined, we know why
 
b = 10;
alert(b); // 10, created at code execution
 
var a = 20;
alert(a); // 20, modified at code execution

关于变量,还有一个重要的知识点。变量相对于简单属性来说,变量有一个特性(attribute):{DontDelete},这个特性的含义就是不同通过delete操作符直接删除变量属性。

a = 10;
alert(window.a); // 10
 
alert(delete a); // true
 
alert(window.a); // undefined
 
var b = 20;
alert(window.b); // 20
 
alert(delete b); // false
 
alert(window.b); // still 20

2018-8-2-再看执行上下文、变量对象

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
Aug 08 Javascript
jquery操作下拉列表、文本框、复选框、单选框集合(收藏)
Jan 08 Javascript
$.extend 的一个小问题
Jun 18 Javascript
深入浅析JavaScript中的constructor
Apr 19 Javascript
页面向下滚动ajax获取数据的实现方法(兼容手机)
May 24 Javascript
jQuery实现两个select控件的互移操作
Dec 22 Javascript
jquery拖动改变div大小
Jul 04 jQuery
微信小程序下拉刷新界面的实现
Sep 28 Javascript
使用wxapp-img-loader自定义组件实现微信小程序图片预加载功能
Oct 18 Javascript
jquery+ajax实现异步上传文件显示进度条
Aug 17 jQuery
JavaScript手写数组的常用函数总结
Nov 22 Javascript
Vue实现下拉加载更多
May 09 Vue.js
JavaScript ECMA-262-3 深入解析(二):变量对象实例详解
Apr 25 #Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
Apr 25 #Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
Apr 25 #Javascript
javascript 函数的暂停和恢复实例详解
Apr 25 #Javascript
详解ES6 CLASS在微信小程序中的应用实例
Apr 24 #Javascript
Vue中函数防抖节流的理解及应用实现
Apr 24 #Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
Apr 24 #Javascript
You might like
PHP 中英文混合排版中处理字符串常用的函数
2007/04/12 PHP
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
2010/11/01 PHP
PHP中使用php5-ffmpeg撷取视频图片实例
2015/01/07 PHP
变量在 PHP7 内部的实现(一)
2015/12/21 PHP
PHP实现限制域名访问的实现代码(本地验证)
2020/09/13 PHP
javascript之典型高阶函数应用介绍
2013/01/10 Javascript
ExtJS下书写动态生成的xml(兼容火狐)
2013/04/02 Javascript
js和jquery使按钮失效为不可用状态的方法
2014/01/26 Javascript
jQuery多个input求和的实现方法
2015/02/12 Javascript
JavaScript中数据结构与算法(二):队列
2015/06/19 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
2015/08/12 Javascript
使用JavaScript实现弹出层效果的简单实例
2016/05/31 Javascript
bootstrap基础知识学习笔记
2016/11/02 Javascript
js滚轮事件兼容性问题需要注意哪些
2016/11/15 Javascript
AngularJS指令与控制器之间的交互功能示例
2016/12/14 Javascript
javascript实现数据双向绑定的三种方式小结
2017/03/09 Javascript
Ionic + Angular.js实现验证码倒计时功能的方法
2017/06/12 Javascript
官方推荐react-navigation的具体使用详解
2018/05/08 Javascript
ES6 class的应用实例分析
2019/06/27 Javascript
jQuery实现轮播图效果demo
2020/01/11 jQuery
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
2017/04/17 Python
python实现画五角星和螺旋线的示例
2019/01/20 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
python中的 zip函数详解及用法举例
2020/02/16 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
Python内置函数locals和globals对比
2020/04/28 Python
python实现mask矩阵示例(根据列表所给元素)
2020/07/30 Python
韩国爱茉莉太平洋化妆品美国站:Amore Pacific US
2016/10/28 全球购物
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
2014年上半年工作自我评价
2014/01/18 职场文书
本科应届生自荐信
2014/06/29 职场文书
新闻编辑求职信
2014/07/13 职场文书
2014年电信员工工作总结
2014/12/19 职场文书
党风廉政建设个人总结
2015/03/06 职场文书
2015年学生会工作总结范文
2015/03/31 职场文书
前端canvas中物体边框和控制点的实现示例
2022/08/05 Javascript