JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析


Posted in Javascript onApril 25, 2020

本文实例讲述了JavaScript ECMA执行上下文。分享给大家供大家参考,具体如下:

介绍

这篇文章我们主要探讨ECMAScript执行上下文和相关的ECMAScript可执行代码。

定义

每次当控制器转到ECMAScript可执行代码的时候,即会进入到一个执行上下文

执行上下文(简称-EC)是一个抽象概念,ECMA-262标准用这个概念同可执行代码(executable code)概念进行区分。

标准规范没有从技术实现的角度准确定义EC的类型和结构;这应该是具体实现ECMAScript引擎时要考虑的问题。

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

可执行代码

可执行代码的概念与抽象的执行上下文的概念是相对的。在某些时刻,可执行代码与执行上下文是等价的。

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

ECStack = [];

每次进入函数 (即使函数被递归调用或作为构造函数) 的时候或者内置的eval函数工作的时候,这个堆栈都会被推入。

全局代码

这种类型的代码是在"程序"级处理的:例如加载外部的js文件或者本地的在<script></script>标签内的代码。全局代码不包括任何函数体内的代码。

在初始化(程序启动)阶段,ECStack是这样的:

ECStack = [
 globalContext
];

函数代码

当进入函数代码(所有类型的函数),ECStack被推入新元素。要注意的是,具体的函数代码不包括内部函数(inner functions)代码。如下所示,我们使函数自己调自己的方式递归一次:

(function foo(bar) {
 if (bar) {
 return;
 }
 foo(true);
})();

那么,ECStack以如下方式被改变:

// first activation of foo
ECStack = [
 <foo> functionContext
 globalContext
];
 
// recursive activation of foo
ECStack = [
 <foo> functionContext ? recursively
 <foo> functionContext
 globalContext
];

每次返回存在的当前执行上下文和ECStack弹出相应的执行上下文的时候,栈指针会自动移动位置,这是一个典型的堆栈实现方式。一个被抛出但是没有被截获的异常,同样存在一个或多个执行上下文。当相关段代码执行完以后,直到整个应用程序结束,ECStack都只包括全局上下文(global context)。

Eval 代码

 eval 代码有点儿意思。它有一个概念: 调用上下文(calling context), 这是一个当eval函数被调用的时候产生的上下文。eval(变量或函数声明)活动会影响调用上下文(calling context)

eval('var x = 10');
 
(function foo() {
 eval('var y = 20');
})();
 
alert(x); // 10
alert(y); // "y" is not defined

ECStack的变化过程:

ECStack = [
 globalContext
];
 
// eval('var x = 10');
ECStack.push(
 evalContext,
 callingContext: globalContext
);
 
// eval exited context
ECStack.pop();
 
// foo funciton call
ECStack.push(<foo> functionContext);
 
// eval('var y = 20');
ECStack.push(
 evalContext,
 callingContext: <foo> functionContext
);
 
// return from eval
ECStack.pop();
 
// return from foo
ECStack.pop();

看到了吧,这是一个非常普通的逻辑调用堆栈

在版本号1.7以上的SpiderMonkey(内置于Firefox,Thunderbird)的实现中,可以把调用上下文作为第二个参数传递给eval。那么,如果这个上下文存在,就有可能影响“私有”(类似以private关键字命名的变量一样)变量。

function foo() {
 var x = 1;
 return function () { alert(x); };
};
 
var bar = foo();
 
bar(); // 1
 
eval('x = 2', bar); // pass context, influence on internal var "x"
 
bar(); // 2

结论

这篇文章的内容是未来分析其他跟执行上下文相关的主题(例如变量对象,作用域链,等等)的最起码的理论基础,这些主题将在后续章节中讲到。

其他参考

这篇文章的内容在ECMA-262-3 标准规范中对应的章节.

英文地址 : ECMA-262-3 in detail. Chapter 1. Execution Contexts

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

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

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

Javascript 相关文章推荐
prototype 1.5 &amp; scriptaculous 1.6.1 学习笔记
Sep 07 Javascript
出现“不能执行已释放的Script代码”错误的原因及解决办法
Aug 29 Javascript
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
Sep 19 Javascript
Javascript 中介者模式实例
Dec 16 Javascript
Js event事件在IE、FF兼容性问题
Jan 01 Javascript
微信小程序开发之animation循环动画实现的让云朵飘效果
Jul 14 Javascript
简单谈谈vue的过渡动画(推荐)
Oct 11 Javascript
微信小程序实现全国机场索引列表
Jan 31 Javascript
Bootstrap table表格初始化表格数据的方法
Jul 25 Javascript
jQuery的Ajax接收java返回数据方法
Aug 11 jQuery
vue单页缓存存在的问题及解决方案(小结)
Sep 25 Javascript
vue+elementUI 实现内容区域高度自适应的示例
Sep 26 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
vue中使用带隐藏文本信息的图片、图片水印的方法
Apr 24 #Javascript
基于Vue实现微前端的示例代码
Apr 24 #Javascript
You might like
[原创]php获取数组中键值最大数组项的索引值
2015/03/17 PHP
php使用ffmpeg向视频中添加文字字幕的实现方法
2016/05/23 PHP
php array_pop 删除数组最后一个元素实例
2016/11/02 PHP
PHP实现的分页类定义与用法示例
2017/07/05 PHP
php实现姓名根据首字母排序的类与方法(实例代码)
2018/05/16 PHP
PHP通过文件保存和更新信息的方法分析
2019/09/12 PHP
javascript跟随滚动效果插件代码(javascript Follow Plugin)
2013/08/03 Javascript
js中函数调用的两种常用方法使用介绍
2014/07/17 Javascript
javascript学习笔记(八)正则表达式
2014/10/08 Javascript
JavaScript实现Iterator模式实例分析
2015/06/09 Javascript
写给小白的JavaScript引擎指南
2015/12/04 Javascript
表单中单选框添加选项和移除选项
2016/07/04 Javascript
AngularJS基础 ng-disabled 指令详解及简单示例
2016/08/01 Javascript
JavaScript在form表单中使用button按钮实现submit提交方法
2017/01/23 Javascript
JS简单判断函数是否存在的方法
2017/02/13 Javascript
基于cookie实现zTree树刷新后展开状态不变
2017/02/28 Javascript
JavaScript高阶函数_动力节点Java学院整理
2017/06/28 Javascript
React教程之Props验证的具体用法(Props Validation)
2017/09/04 Javascript
VUE前端cookie简单操作
2017/10/17 Javascript
详解javascript函数写法大全
2019/03/25 Javascript
微信小程序之onLaunch与onload异步问题详解
2019/03/28 Javascript
在微信小程序中使用vant的方法
2019/06/07 Javascript
微信小游戏之使用three.js 绘制一个旋转的三角形
2019/06/10 Javascript
使用vue引入maptalks地图及聚合效果的实现
2020/08/10 Javascript
简单学习Python多进程Multiprocessing
2017/08/29 Python
对Python3 * 和 ** 运算符详解
2019/02/16 Python
Python同步遍历多个列表的示例
2019/02/19 Python
python学习——内置函数、数据结构、标准库的技巧(推荐)
2019/04/18 Python
python实现将json多行数据传入到mysql中使用
2019/12/31 Python
全网最细 Python 格式化输出用法讲解(推荐)
2021/01/18 Python
Canvas 文本填充线性渐变的使用详解
2020/06/22 HTML / CSS
戴尔英国官网:Dell英国
2017/05/27 全球购物
Eyeko美国:屡获殊荣的睫毛膏、眼线笔和眉妆
2018/07/05 全球购物
工作自荐信
2013/12/11 职场文书
异地年检委托书范本
2014/09/24 职场文书
学校领导四风问题整改措施思想汇报
2014/10/09 职场文书