js进阶之执行上下文对象、执行上下文栈

92 阅读2分钟

变量提升和函数声明提升

var a = 1;

function fn() { 
  console.log(a); // undefined
  var a = 2;
}

fn();

以上代码打印输出了undefined。

这就是变量声明提升-- 在全局作用域和函数作用域中声明的变量,会在预编译阶段被提升到代码头部。

所以相当于:

function fn() { 
  var a;
  console.log(a); // undefined
  a = 2;
}

接下来函数声明提升:

fn(); 


function fn() { 
  console.log(a);
  let a = 2;
}

以上代码,可以正常执行,没有报错。

函数声明提升--在预编译阶段会将函数声明提升到该作用域顶部。所以在预编译阶段fn已经被挂载在window对象上了。

执行上下文对象

我们都知道,js代码执行分为三个阶段:语法分析预编译,最后才是执行代码

语法分析分为词法分析、转换为ast、转成机器语言。这里不作赘述。

那预编译阶段做了什么呢?

  1. 创建全局执行上下文对象
  • 确认this指向全局执行上下文对象window
  • 全局环境下声明的全局变量挂载在window上,值为undefined(变量声明提升)
  • 全局环境下声明的全局函数挂载在window上,值为函数本身(函数声明提升)
  1. 创建函数执行上下文对象
  • 确认this指向调用函数的对象
  • 函数内声明的var变量,挂载在上下文对象上,值为undefined
  • 函数内声明的函数声明,挂载在上下文对象上,值为函数本身
  • 函数入参赋值,挂载在上下文对象上
  1. 创建执行上下文栈,用来存放执行中的执行上下文对象

执行上下文栈

用来存放执行上下文的栈,先入后出。

截屏2023-02-05 上午10.16.41.png