JS|执行上下文(Execution Content)

先把单独的概念拆出来理解
在放到整体中去理解


执行上下文(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函数时创建的,已经不被推荐使用

每次创建执行上下文的时候都分为两个阶段进行:

  1. 创建阶段
    • 创建作用域链(outer
    • 创建变量、函数和参数
    • 确定this
  2. 执行阶段

一个很好的比喻就是:我们在创建阶段创建一个模版,然后在执行阶段用相关信息去填充模版

关于Execution Context有5个关键点:

  1. 单线程
  2. 同步执行
  3. 1个全局执行上下文
  4. 无限的函数执行上下文
  5. 每个函数都会创建一个新的执行上下文,甚至是调用自身

那么执行上下文里面都有什么呢?其实我们可以大概的把它当做一个对象:

executionContextObj = {
'scopeChain'     :{/* variableObject + all parent execution context's variableObject */},
'variableObject' :{ /* function arguments / parameters, inner variable and function declarations */ },
'this'          : {}
}
其中有作用域链,变量对象和this,而变量对象又可以分为变量环境和词法环境
ES6之前用var定义的变量都在变量环境中存储,而ES6之后块级作用域声明的变量都在词法环境中存储
复制代码

解释器的执行过程大致是这样的:

  1. 当需要调用一个函数时

  2. 在执行函数代码之前,创建Execution Context

  3. 进入创建阶段

    1. 初始化Scope Chain
    2. 创建variable object
    3. 创建argument object,检查参数的上下文,初始化名称和值并创建引用副本
    4. 扫描函数声明的上下文
    5. 对于找到的每个函数,在其中创建一个属性,该属性是确切的函数名称,该属性具有执行内存中函数的引用指针
    6. 如果函数名已经存在,引用指针将会被覆盖
    7. 扫描变量声明的上下文
    8. 对于找到的每个变量声明,都会在variable object中创建一个属性,并将值初始化为undefined
    9. 如果变量名已存在于variable object中,测什么都不做并继续扫描
    10. 确定this上下文内的值
  4. 执行阶段

    在上下文中运行函数代码,并在代码逐行执行时分配变量值

参考文章
Understanding Execution Context and Execution Stack in Javascript

Understanding the Execution Context in JavaScript

What is the Execution Context & Stack in JavaScript?

JavaScript Execution Context

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享