javascript执行环境(执行期上下文)详解
javascript执行环境(执行期上下文)
当js控制器(control)进入可执行代码时,控制器会进入一个执行环境,活动的多个执行环境构成执行环境栈,最上面的是正在运行的执行环境,当控制器进入一个新的执行环境时,新的执行环境被放到栈最顶端。
执行环境包含以下三个组件: 组件 作用目的
词法环境 执行环境内的代码创建的标识符引用的一个词法环境对象
变量环境 执行环境内的代码通过变量表达式和函数表达式创建的绑定的一个词法环境对象。
this绑定 指定该执行环境内的this关键字所关联的值。 执行环境的建立 当执行全局代码,使用eval函数,执行一个函数时,会创建执行环境。
创建执行环境分两步,第一步初始化执行环境,下面是全局代码和函数的初始化过程:
1,全局代码
ECMA全局执行环境C的初始化过程:
(1)将变量环境设置为全局环境
(2)将词法环境设置为全局环境
(3)将this绑定设置为全局对象 2,进入函数代码
当进入一个函数对象F,调用者提供的thisArg,调用者提供的argumentsList时,执行以下步骤
(1)设置this:
if(函数是严格模式代码){
this=thisArg;
}else if(thisArg===null||thisArg=undefined){
this=全局对象
}else if(Type(thisArg!==Object)){
this=ToObject(thisArg);
}else{
this=thisArg;
}
(2)以F的内部属性[[Scope]]作为参数调用来调用声明式执行环境,结果记为localEnv,
设置词法环境为localEnv,设置变量环境为localEnv
(3)令code为F的内部属性[[Code]] 接下来就是声明绑定初始化过程,此过程比较复杂,主体过程如下:
1,env=当前执行环境的变量环境
2,if(eval代码){
configurableBindings=true;
}else{
configurableBindings=false;
}
3,if(strict mode code){
strict=true;
}else{
strict=false;
}
4,if(函数代码){
func=调用code的内部属性[[Call]]的结果
names=func的形式参数[[FormalParameters]]内部属性
argCount=args的长度
n=0
foreach(argName in names){
n++
v=n>argsCount?undefined:v=args[n]
argAlreadyDeclared=env.HasBinding(argName)
if(argAlreadyDeclared===false){
env.CreateMutableBinding(argName)//变量环境创建可变绑定
}
env.SetMutableBinding(argName,v,strict)//变量环境设置可变绑定
}
}
5,对于code中的每一个函数声明f,按以下步骤进行:
fn=f的Identifier
fo=f的初始化结果
funcAlreadyDeclared=env.HasBinding(fn)
if(funcAlreadyDeclared===false){
env.CreateMutableBinding(fn,configurableBindings)
}else if(env===全局环境记录对象){
go=全局对象
existingProp=以fn为参数调用go的内部属性[[GetProperty]]的结果
if(existingProp的[[Configurable]]内部属性===true){
go.[[DefineOwnProperty]](fn,Property Descriptor {[[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true , [[Configurable]]: configurableBindings },true)
}else if(existingProp是访问器属性描述符 或 existingProp 没有属性值{[[Writable]]: true, [[Enumerable]]: true}){
Throw a TypeError exception
}
env.SetMutableBinding(fn,fo,strict)
}
6,argumentsAlreadyDeclared=env.HasBinding(arguments)
7,if(code is function code and argumentsAlreadyDeclared===false){
argsObj=CreateArgumentsObject(func, names, args, env , strict)
if(strict===true){
env.CreateImmutableBinding(arguments)
env.InitializeImmutableBinding(arguments,argsObj)//严格模式的arguments不可变
}else{
env.CreateMutableBinding(arguments)
env.SetMutableBinding(arguments,args,false)//非严格模式arguments可变
}
}
8,对于code中的每一个变量声明d:
dn=d的Identifier
varAlreadyDeclared=env.HasBinding(dn)
if(varAlreadyDeclared===false){
env.CreateMutableBinding(dn,configurableBindings)
env.SetMutableBinding(dn,undefined,strict)
}
javascript执行环境(执行期上下文)详解的更多相关文章
- javascript中的this作用域详解
javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...
- JavaScript对象的property属性详解
JavaScript对象的property属性详解:https://www.jb51.net/article/48594.htm JS原型与原型链终极详解_proto_.prototype及const ...
- VirtualBox开发环境的搭建详解(转)
VirtualBox开发环境的搭建详解 有关VirtualBox的介绍请参考:VirtualBox_百度百科 由于VirtualBox官网提供的搭建方法不够详细,而且本人在它指导下,从下载所需的开 ...
- Javascript 调试利器 Firebug使用详解
Javascript 调试利器 Firebug使用详解 有时候,为了更清楚方便的查看输出信息,我们可能需要将一些调试信息进行分组输出,那么可以使用console.group来对信息进行分组,在组信息输 ...
- Linux环境fork()函数详解
Linux环境fork()函数详解 引言 先来看一段代码吧, 1 #include <sys/types.h> 2 #include <unistd.h> 3 #include ...
- JavaScript中return的用法详解
JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...
- fabric网络环境启动过程详解
这篇文章对fabric的网络环境启动过程进行讲解,也就是我们上节讲到的启动测试fabric网络环境时运行network_setup.sh这个文件的执行流程 fabric网络环境启动过程详解 上一节我们 ...
- “全栈2019”Java多线程第八章:放弃执行权yield()方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- javascript 中合并排序算法 详解
javascript 中合并排序算法 详解 我会通过程序的执行过程来给大家合并排序是如何排序的... 合并排序代码如下: <script type="text/javascript& ...
随机推荐
- Liferay7 BPM门户开发之38: OSGi模块化Bndtools、Maven、Gradle开发构建入门
前言 OSGi是目前动态模块系统的事实上的工业标准,它适用于任何需要模块化.面向服务.面向组件的应用程序.Eclipse如此庞大和复杂的插件体系,就是基于OSGi.Liferay也是基于OSGi.OS ...
- 在微软伪静态处理机制下action导致伪静态的地址重现的问题
伪静态前的地址:/sc/ProductList.aspx?pClass=0&descType=2&minPrice=1&maxPrice=11 伪静态后的地址:/product ...
- Vue.js学习笔记(8)拖放
小颖在目前负责的项目中,负责给同事提供所需组件,在这期间,我们家大颖姐姐让我 写个拖拽组件,一开始我是用click实现,先将你要拖拽的dom点一下,然后再点你要放的位置,这个dom再通过小颖写的方法, ...
- Android随笔之——获取EditText光标所在行行号
由于项目需求,需要获取EditText光标当前所在行行号,可是翻遍Android文档.问遍度娘都没发现,于是在博客园中提问,碰见了好心人告诉了我答案,谨以以下代码献给有需要的人 private int ...
- YII 的源码分析(-)
做为源码分析的首秀,我就挑了yii(读作歪依依而不是歪爱爱):它的赞美之词我就不多说了,直接入正题.先准备材料,建议直从官网下载yii的源码包(1.1.15). 在demos里边有一个最简单的应用—h ...
- MySQL数据类型的验证
CHAR char (M) M字符,长度是M*字符编码长度,M最大255. 验证如下: mysql)) default charset=utf8; ERROR (): ); use BLOB or T ...
- 分享一个 @user 前端插件
开源地址:https://github.com/yuezhongxin/Mention.js 插件效果:类似于微博或 github 中 @user 列表效果. 这是个二次开发的插件,花了几天时间,对 ...
- C#将一个excel工作表根据指定范围拆分为多个excel文件
C#将一个excel工作表根据指定范围拆分为多个excel文件 微软Excel没有提供直接的方法来拆分excel文件,因此要拆分一个excel文件最简单的方法可能就是手动剪切和粘贴了,除此之外,还有其 ...
- (九)WebGIS中的矢量查询(针对AGS和GeoServer)
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在第七章里我们知道了WebGIS中要素的本质是UICompo ...
- maven pom中 设置远程仓库url
<repositories> <!--<repository>--> <!--<id>spring-snapshots</id>--& ...