先把单独的概念拆出来理解
在放到整体中去理解
执行上下文(Execution Content):是JavaCsript代码执行环境的抽象概念
负责管理执行上下文的是JavaScript引擎,JS引擎做的第一件事情就是下载Js源代码,收到代码之后,会运行到解析器中并创建一个抽象语法?(AST)。之后就会默认进入全局执行上下文中,从此开始每次调用函数都会创建一个新的函数执行上下文。
- 全局执行上下文(Global Execution Context):全局环境中只有一个,一个全局环境还包含一个全局对象,一旦JS引擎在全局执行上下文中,它就会默认在全局内存中创建两个属性:this对象和window对象。在非严格模式下this的值等于全局环境
- 函数执行上下文(Function Execution Context):每次执行函数时,都会为该函数创建一个新的执行上下文,JS引擎会默认创建一个argument对象和this对象。所以每个函数都有自己的执行上下文,它是在代码执行调用函数时创建的,而不是之前
- Eval执行上下文(Eval Execution Context):在调用eval函数时创建的,已经不被推荐使用
每次创建执行上下文的时候都分为两个阶段进行:
- 创建阶段
- 创建作用域链(outer)
- 创建变量、函数和参数
- 确定this
- 执行阶段
一个很好的比喻就是:我们在创建阶段创建一个模版,然后在执行阶段用相关信息去填充模版
关于Execution Context有5个关键点:
- 单线程
- 同步执行
- 1个全局执行上下文
- 无限的函数执行上下文
- 每个函数都会创建一个新的执行上下文,甚至是调用自身
那么执行上下文里面都有什么呢?其实我们可以大概的把它当做一个对象:
executionContextObj = {
'scopeChain' :{/* variableObject + all parent execution context's variableObject */},
'variableObject' :{ /* function arguments / parameters, inner variable and function declarations */ },
'this' : {}
}
其中有作用域链,变量对象和this,而变量对象又可以分为变量环境和词法环境
ES6之前用var定义的变量都在变量环境中存储,而ES6之后块级作用域声明的变量都在词法环境中存储
复制代码
解释器的执行过程大致是这样的:
-
当需要调用一个函数时
-
在执行函数代码之前,创建Execution Context
-
进入创建阶段
- 初始化Scope Chain
- 创建variable object
- 创建argument object,检查参数的上下文,初始化名称和值并创建引用副本
- 扫描函数声明的上下文
- 对于找到的每个函数,在其中创建一个属性,该属性是确切的函数名称,该属性具有执行内存中函数的引用指针
- 如果函数名已经存在,引用指针将会被覆盖
- 扫描变量声明的上下文
- 对于找到的每个变量声明,都会在variable object中创建一个属性,并将值初始化为undefined
- 如果变量名已存在于variable object中,测什么都不做并继续扫描
- 确定this上下文内的值
-
执行阶段
在上下文中运行函数代码,并在代码逐行执行时分配变量值
参考文章
Understanding Execution Context and Execution Stack in Javascript
Understanding the Execution Context in JavaScript
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END