JavaScript 执行上下文与变量提升详解

4 阅读2分钟

前言

  • 为什么 var声明的变量可以先访问后定义?

  • 为什么函数可以在声明前调用?

  • 为什么 let 会出现暂时性死区?

这些问题背后,都和 执行上下文变量提升 有关。


一、什么是执行上下文?

执行上下文可以简单理解为:

JavaScript 代码执行时所在的环境。

JavaScript 在执行代码时,并不是简单地一行一行执行,它会先创建执行上下文,然后再执行代码。


二、执行上下文的类型

主要有三种:

  1. 全局执行上下文

  2. 函数执行上下文

  3. eval 执行上下文(较少用)


三、什么是变量提升?

变量提升指的是:

变量和函数的声明,会在代码执行前被处理。

例如:

console.log(a);
var a = 10;

看起来像是先访问后声明,但不会报错,而是输出:

undefined

因为它大致相当于:

var a;
console.log(a);
a = 10;

这就是变量提升。


四、函数提升

函数声明也会提升,而且优先级通常高于var

sayHello();

function sayHello() {
  console.log('hello');
}

这段代码可以正常执行。


五、var 和 function 的区别

console.log(a); // undefined
var a = 10;

foo(); // foo

function foo() {
  console.log('foo');
}

原因:

  • var

    只提升声明,不提升赋值

  • function

    会整体提升


六、let / const 为什么不能先访问?

console.log(a);
let a = 10;

这里会报错。

因为letconst虽然也会在作用域开始时被“记录”,但在正式声明前不能访问,这段区域称为:

暂时性死区(TDZ)


七、执行上下文大致过程

执行上下文可以粗略理解为两个阶段:

1)创建阶段

  • 建立作用域

  • 处理 this

  • 收集变量和函数声明

2)执行阶段

  • 按顺序执行代码
  • 完成赋值
  • 调用函数

八、总结

执行上下文和变量提升是理解 JavaScript 执行机制的重要基础。

重点记住:

  • var

    提升声明,不提升赋值

  • function

    整体提升

  • let / const

    有暂时性死区

  • JavaScript 会先创建执行上下文,再执行代码