Javascript执行上下文和执行栈
什么是执行上下文?
执行上下文就是当前JavaScript代码被解析和执行时所在环境的抽象概念,JavaScript中运行任何的代码都是在执行上下文。
什么是执行栈?
执行栈,在其他编程语言中也被叫做调用栈,具有LIFO(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文。当JavaScript引擎首次读取脚本时,它会创建一个全局执行上下文并将其推入当前的执行栈。每当发生一个函数调用,引擎都会为该函数创建一个新的执行上下文,并将其推到当前执行栈的顶端。引擎会运行执行上下文在执行栈顶端的函数,当此函数运行完成后,其对应的执行上下文将会从执行栈中弹出,上下文控制权将移到当前执行栈的下一个执行上下文。所以程序结束以前,执行栈最底部永远有一个globalContext。
执行上下文的类型
执行上下文总共有三种类型:
一、全局执行上下文:这是默认的,基础的执行上下文。不在任何函数中的代码都位于全局执行上下文中,做了两件事:1.创建一个全局对象,在浏览器中这个全局对象就是window对象。2.将this指针指向这个全局对象。一个程序中只能存在一个全局执行上下文。
二、函数执行上下文:每次调用函数时,都会为该函数创建一个新的执行上下文。每个函数都拥有自己的执行上下文,但是只有在函数被调用的时候才会被创建。一个程序中可以存在任意数量的函数执行上下文。每当一个新的执行上下文被创建,它都会按照特定的顺序执行一系列步骤。
三、Eval函数执行上下文:运行在eval函数中的代码也获得自己的执行上下文,不常用函数,不建议使用。
执行上下文如何被创建?
执行上下文分两个阶段创建:1)创建阶段;2)执行阶段
一、创建阶段:在任意的JavaScript代码被执行之前,执行上下文处于创建阶段。在创建阶段中总共发生了三件事情:
1.确定this的值,也被称为This Binding;
2.LexicalEnvironment(词法环境)组件被创建。
3.VariableEnvironment(变量环境)组件被创建。

创建阶段
Ⅰ、This Binding:
在全局执行上下文中,this的值指向全局对象,在浏览器中,this的值指向window对象。在函数指向上下文中,this的值取决于函数的调用方式。如果它被一个对象引用调用,那么this的值被设置为该对象,否则this的值被设置为全局对象或undefined(严格模式下)。
Ⅱ、LexicalEnvironment(词法环境):
ES6文档将词法环境定义为:词法环境是一种规范类型,基于ECMAScript代码的词法嵌套结构来定义标识符与特定变量和函数的关联关系(environment record)和可能为空引用(null)的外部词法环境组成。简而言之,词法环境是一个包含标识符变量映射的结构。(这里的标识符表示变量/函数的名称,变量是对实际对象【包含函数类型对象】或原始值的引用)
在LexicalEnvironment(词法环境)中,有两个部分组成:(1)环境记录(environment record):是存储变量和函数声明的实际位置 (2)对外部环境的引用:意味着它可以访问外部词法环境。
LexicalEnvironment(词法环境)有两种类型:
1.全局环境(在全局执行上下文中)是一个没有外部环境的词法环境。全局环境的外部环境引用为null。它拥有一个全局对象(window对象)及其关联的方法和属性(例如数组方法)以及任何用户自定义的全局变量,this的值指向这个全局对象。
2.函数环境,用户在函数中定义的变量被存储在环境记录中,对外部环境的引用可以是全局,也可以是包含内部函数的外部函数环境。
注意:对于函数环境而言,环境记录还包含了一个arguments对象,该对象包含了索引和传递给函数的参数之间的映射以及传递给函数的长度(数量)。

环境记录同样有两种类型:
1.声明性环境记录:存储变量、函数和参数。一个函数环境包含声明性环境记录。
2.对象环境记录:用于定义在全局执行上下文中出现的变量和函数的关联。全局环境包含对象环境记录。
Ⅲ、VariableEnvironmen(变量环境):
它也是一个词法环境,其EnvironmentRecord包含了由VariableStatements在此执行上下文创建的绑定。它具有上面定义的语法环境的所有属性。与LexicalEnvironment的区别在于前者用于存储函数声明和变量(let和const)绑定,而后者仅用于存储变量(var)绑定。
结合实例分析:
let a=10;
const b=20;
var c;
function addFun (e,f){
var g =50;
return e*f*g;
}
c = addFun(30,40) /*GlobalExecutionContext = {
ThisBinding = <Global Object> //确定this
LexicalEnvironment = {
EnvironmentRecord:{
Type:'Object' //全局环境
//标识符绑定
a:<uninitialized>,
b:<uninitialized>,
addFun:<Func>
},
outer:<null> //对外部环境的引用
}, //词法环境
VariableEnvironment = {
EnvironmentRecord:{
Type:'Object' //全局环境
//标识符绑定
c:undefined
},
outer:<null> //对外部环境的引用
} //变量环境
}
FunctionExecutionContext = {
ThisBinding = <Global Object> //确定this
LexicalEnvironment = {
EnvironmentRecord:{
Type:'Declarative' //函数环境
//标识符绑定
Arguments:{0:30,1:40,length:2}
},
outer:<GlobalLexicalEnvironment>//对外部环境的引用
}, //词法环境
VariableEnvironment = {
EnvironmentRecord:{
Type:'Declarative' //函数环境
//标识符绑定
g:undefined
},
outer:<GlobalLexicalEnvironment>//对外部环境的引用
} //变量环境
}*/
只有在addFun调用的时候才会创建函数执行上下文。创建之初,代码会被扫描并解析变量和函数声明,其中函数声明存储在环境之中,而变量会被设置为undefined(在var情况下)或保持未初始化(在let和const情况下)。这也是为什么可以在声明之前访问var定义的变量(尽管是undefined),但如果在let或const之前访问定义的变量会提示引用错误的原因。
这就是所谓的变量提升。
函数上下文
在函数上下文中,用活动对象(activation object,AO)来表示变量对象。
活动对象和变量对象的区别在于:
1.变量对象(VO)是规范上或者是JS引擎上实现的,并不能在JS环境中直接访问。
2.当进入到一个执行上下文后,这个变量才会被激活,所以叫活动变量(AO),这个时候活动变量上的各种属性才能被访问。
调用函数的时候,会为其创建一个Arguments对象,并自动初始化局部变量arguments,指代该Arguments对象。所有作为参数传入的值都会成为Arguments对象的数组元素。
二、执行阶段分为两个阶段。注:在执行阶段,如果JavaScript引擎在源代码中声明的位置找不到let变量的值,那么将为其分配undefined的值。
Ⅰ、进入执行阶段
此时的变量对象会进行初始化:
1.函数的所有形参:没有实参,属性值设为undefined。
2.函数声明:如果变量对象已经存在相同的属性,则完全替换这个属性。
3.变量声明:如果变量名称跟已经声明的形参或函数相同,则变量声明不会干扰已经存在的属性。
Ⅱ、代码执行
这个阶段会顺序执行代码,修改变量对象的值。
执行阶段总结:
1.全局上下文的变量初始化是全局对象;
2.函数上下文的变量对象初始化只包括Arguments对象;
3.在进入执行上下文时会给变量对象添加形参,函数声明,变量声明等初始属性值
4.在代码执行阶段,会再次修改变量对象的属性值。
Javascript执行上下文和执行栈的更多相关文章
- 深入理解 JavaScript 执行上下文和执行栈
前言 如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制.执行上下文和执行栈是 JavaScript ...
- 转:JS高级学习笔记(8)- JavaScript执行上下文和执行栈
必看参考: 请移步:博客园 JavaScript的执行上下文 深入理解JavaScript执行上下文和执行栈 JavaScript 深入之执行上下文 写在开头 入坑前端已经 13 个月了,不能再称自己 ...
- 理解 Javascript 执行上下文和执行栈
如果你是一名 JavaScript 开发者,或者想要成为一名 JavaScript 开发者,那么你必须知道 JavaScript 程序内部的执行机制.理解执行上下文和执行栈同样有助于理解其他的 Jav ...
- JavaScript进阶之执行上下文和执行栈
js引擎的执行过程 执行上下文和执行栈属于js引擎的执行过程的预编译阶段. 执行上下文(Execution Context) 执行上下文是当前 JavaScript 代码被解析和执行时所在环境的抽象概 ...
- js执行上下文和执行栈
执行上下文就是JavaScript 在被解析和运行时环境的抽象概念,JavaScript 运行任何代码都是在执行上下文环境中运行的,执行上下文包括三个周期:创建——运行——销毁,重点说一下创建环节. ...
- 【进阶1-1期】理解JavaScript 中的执行上下文和执行栈(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://mp.weixin.qq.com/s/tNl5B4uGdMkJ2bNdbbo82g 阅读笔记 执行上下文是当前 JavaScrip ...
- JavaScript 中的执行上下文和执行栈
JavaScript - 原理系列 在日常开发中,每当我们接手一个现有项目后,我们总喜欢先去看看别人写的代码.每当我们看到别人写出很酷的代码的时候,我们总会感慨!写出这么优美而又简洁的代码的兄弟到 ...
- javascript执行上下文和变量对象
执行上下文(execution context): 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念. js语言是一段一段的顺序执行,这个“段”其实就是我们说的这个执行上 ...
- Js 执行上下文和作用域
1.执行上下文和执行栈 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行. 执行上下文的生命周期包括三个阶 ...
随机推荐
- Xshell连接ubuntu server端的vim(256色彩配置)
VIM主题(Xshell端) [注]我的配置:Xshell连接VMware Workstation Pro下的Ubuntu 18 server版(要注意这里的server版,好似该版本没有下述的256 ...
- Mac 上的 GLFW 环境配置
背景:GLFW 一.下载和编译 从官网下载源代码包:http://www.glfw.org/download.html (我下载的是 github 仓库上的) 按官方指南编译.总结如下: cd glf ...
- emwin之创建窗口与窗口回调函数的句柄是一致的
@2019-04-28 [小记] 由函数GUI_CreateDialogBox 创建的窗口所返回的句柄与回调函数形参中的窗口句柄参数是一样的
- 镜像站nginx
server { listen 80 default_server; charset utf-8; server_name monitor.autoai.com; access_log /srv/lo ...
- SAM求多个串的最长公共子串
又学到一个\(SAM\)的新套路QvQ 思路 考虑用其中的一个串建个\(SAM\),然后用其他的串在上面匹配,匹配时更新答案 首先有一个全局变量\(len\),表示当前已匹配的长度.假设目前在点\(u ...
- python学习笔记之集合
集合:可变的数据类型,他里面的元素必须是不可变的数据类型,无序,不重复. {}'''# set1 = set({1,2,3})# set2 = {1,2,3,[2,3],{'name':'alex'} ...
- Java基础 -- 深入理解Java异常机制
异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的异常. ...
- 关于Mac 系统mysql 乱码问题
这是由于客户端和服务端的编码没有同一 首先我们先在终端连接mysql 连接方法 mysql -u 用户名 -p 即可 然后输入你的密码 这里就不多说了 然后我们输入 show variabl ...
- Django mysql应用
环境:python3.Django2 1.安装驱动mysqlclient pip3 install mysqlclient 2.创建一个数据库 CREATE DATABASE database_nam ...
- vue路由实现多视图的单页应用
多视图的单页应用:在一个页面中实现多个页面不同切换,url也发生相应变化. router-view结合this.$router.push("/pickUp")实现,效果如下: 当点 ...