# 深入执行上下文、词法环境、变量环境

# 执行上下文的概念

什么是执行上下文

javascript 代码解析和执行时所在的环境

# 执行上下文的类型

# 全局执行上下文

  • 浏览器环境中全局对象是window, 在node环境中全局对象是global
  • js代码开始运行后。首先进入全局执行上下文环境中,不在任何函数中的js代码都会在全局执行上下文中
  • 一个js程序中只存在一个全局执行上下文。创建时会压人栈底,只有当程序结束时才会弹出
  • 全局执行上下文会做两件事。1.创建全局对象,2.将this指向这个全局对象

# 函数执行上下文

  • 函数每次调用都会产生一个新的函数执行上下文,每个函数都拥有自己的执行上下文,但是只有调用的时候才会被创建
  • 函数执行上下文的生命周期分为两个阶段。创建和执行
  • 每一个执行上下文中都有以下三个属性
    • 作用域链 scope chain
    • VO变量对象 // variableObject -> 初始化变量、函数、形参等
    • this

# Eval执行上下文

eval函数执行时产生的执行上下文。

# 执行上下文栈

  • 首先创建全局执行上下文, 压入栈底
  • 每当调用一个函数时,创建函数的函数执行上下文。并且压入栈顶
  • 当函数执行完成后,会从执行上下文栈中弹出,js引擎继续执栈顶的函数。
function fun1(){
    console.log('func1')
    fun2()
}
function fun2(){
    console.log('func2')
}
fun1()	
/*
*		                 fun2
*	          fun1      fun1	   fun1	
* global => global => global => global => global
*/

# 执行上下文生命周期

# 变量对象VO和活动对象AO

变量对象VO

VO 对应的是函数创建阶段,JS 解析引擎进行预解析时,所有的变量和函数的声明,统称为 Variable Object。该变量与执行上下文相关,知道自己的数据存储在哪里,并且知道如何访问。VO 是一个与执行上下文相关的特殊对象,它存储着在上下文中声明的以下内容:

  • 变量 (var, 变量声明)
  • 函数声明
  • 函数的形参
function add(a, b) {
  var sum = a + b;
  function say() {
    alert(sum);
  }
  return sum;
}
// sum,say,a,b 组合的对象就是VO,不过该对象的值基本上都是undefined

活动对象(AO)

AO 对应的是函数执行阶段,当函数被调用执行时,会建立一个执行上下文,该执行上下文包含了函数所需的所有变量,该变量共同组成了一个新的对象就是 Activetion Object。该对象包含了:

  • 函数的所有局部变量
  • 函数的所有命名参数
  • 函数的参数集合
  • 函数的 this 指向
function add(a, b) {
  var sum = a + b;
  function say() {
    alert(sum);
  }
  return sum;
}
add(4, 5);
//  JS对象来表示AO
//  AO = {
//        this : window,
//        arguments : [4,5],
//        a : 4,
//        b : 5,
//        say : ,
//        sum : undefined
//  }

# 创建阶段

  • 创建作用域链
  • 通过变量对象VO创建活动AO
    • 首先创建arguments对象
    • 创建形参实参的键值对
    • 创建函数声明
    • 创建变量声明

# 执行阶段

  • 变量赋值。函数引用,执行其他代码逻辑
  • 当执行完毕后。执行上下文出栈,等待垃圾回收机制回收

# 函数申明提前

从AO对象的创建过程我们就可以发现,AO对象是先扫描函数体内的函数声明才去扫描变量声明。所以这也就是为啥会有声明提前。

# 变量提升

AO对象创建时已经将函数内部的变量提前扫描声明。是指在函数执行的过程中开始依次赋值。

# 词法环境和变量环境

# 词法环境(LexicalEnvironment)

# 变量环境(VariableEnvironment)

# 代码执行阶段

Last Updated: 10/25/2022, 9:07:41 PM