全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-16 8 分钟 ✍️ juanwangdev

JavaScript 执行上下文与调用栈

执行上下文是 JavaScript 代码执行的环境,调用栈管理着执行上下文的执行顺序。

执行上下文类型

类型创建时机特点
全局执行上下文脚本加载时唯一,this 指向 window/global
函数执行上下文函数调用时每次调用创建新的
Eval 执行上下文eval 执行时不推荐使用

执行上下文结构

JavaScript
┌────────────────────────────────────┐
│         执行上下文                   │
├────────────────────────────────────┤
│  Variable Environment (变量环境)    │
│  - var 声明的变量                    │
│  - 函数声明                          │
├────────────────────────────────────┤
│  Lexical Environment (词法环境)     │
│  - let/const 声明的变量              │
│  - 块级作用域                        │
├────────────────────────────────────┤
│  This Binding (this 绑定)           │
├────────────────────────────────────┤
│  Outer Reference (外部引用)          │
│  - 作用域链                          │
└────────────────────────────────────┘

执行上下文生命周期

1. 创建阶段

JavaScript
// 代码执行前
var a = 1;
let b = 2;
function foo() {}

// 创建阶段执行上下文
ExecutionContext = {
  VariableEnvironment: {
    a: undefined,    // var 变量提升
    foo: <function>   // 函数声明提升
  },
  LexicalEnvironment: {
    b: <uninitialized> // let/const 暂时性死区
  },
  ThisBinding: window
}

2. 执行阶段

JavaScript
// 变量赋值
ExecutionContext = {
  VariableEnvironment: {
    a: 1,
    foo: <function>
  },
  LexicalEnvironment: {
    b: 2
  },
  ThisBinding: window
}

变量提升

var 提升

JavaScript
console.log(a); // undefined(不是 ReferenceError)
var a = 1;

// 等价于
var a;
console.log(a);
a = 1;

函数声明提升

JavaScript
foo(); // "Hello" - 函数声明完整提升

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

bar(); // TypeError - 函数表达式只提升变量
var bar = function() {
  console.log('World');
};

let/const 暂时性死区

JavaScript
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 1;

// TDZ: 变量创建到初始化之间的区域
{
  // TDZ 开始
  console.log(b); // ReferenceError
  let b = 2;      // TDZ 结束
}

作用域链

链式查找

JavaScript
const globalVar = 'global';

function outer() {
  const outerVar = 'outer';

  function inner() {
    const innerVar = 'inner';
    console.log(innerVar);  // 当前作用域
    console.log(outerVar);   // 外部作用域
    console.log(globalVar);  // 全局作用域
  }

  inner();
}

outer();

作用域链结构

JavaScript
inner 执行上下文
    ↓ [Outer Reference]
outer 执行上下文
    ↓ [Outer Reference]
全局执行上下文

调用栈(Call Stack)

工作原理

JavaScript
function first() {
  console.log('first start');
  second();
  console.log('first end');
}

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

first();

// 调用栈变化
// 1. [global]
// 2. [global, first]
// 3. [global, first, second]
// 4. [global, first]  ← second 出栈
// 5. [global]         ← first 出栈

栈溢出

JavaScript
function recurse() {
  recurse(); // 无限递归
}
recurse();

// RangeError: Maximum call stack size exceeded

调用栈最大深度

JavaScript
// 不同引擎限制不同
// V8 约 10000 层
function testStack(depth = 0) {
  try {
    return testStack(depth + 1);
  } catch (e) {
    return depth;
  }
}
console.log(testStack()); // 约 10000+

执行上下文示例分析

JavaScript
const x = 10;

function foo(a) {
  var b = 20;
  let c = 30;

  function bar() {
    let d = 40;
    console.log(a, b, c, d, x);
  }

  bar();
}

foo(5);

// 执行上下文创建顺序
// 1. 全局执行上下文
// 2. foo 函数执行上下文
// 3. bar 函数执行上下文

全局执行上下文

JavaScript
GlobalExecutionContext = {
  LexicalEnvironment: {
    x: 10
  },
  ThisBinding: window
}

foo 执行上下文

JavaScript
FooExecutionContext = {
  VariableEnvironment: {
    b: undefined  20,
    bar: <function>
  },
  LexicalEnvironment: {
    a: 5,
    c: <uninitialized>  30
  },
  OuterReference: GlobalExecutionContext,
  ThisBinding: window
}

bar 执行上下文

text
BarExecutionContext = {
  LexicalEnvironment: {
    d: 40
  },
  OuterReference: FooExecutionContext,
  ThisBinding: window
}

this 绑定确定时机

text
const obj = {
  name: 'obj',
  greet: function() {
    console.log(this.name);
  }
};

const greet = obj.greet;

obj.greet();   // 'obj' - obj 调用
greet();       // undefined - window 调用

// this 在执行上下文创建时确定
// 而不是词法分析时

执行上下文在函数调用时创建,this 绑定取决于调用方式。

要点总结

概念说明
执行上下文代码执行的环境
调用栈管理执行上下文的栈结构
变量提升var 和函数声明提前
TDZlet/const 初始化前的区域
作用域链变量查找链路
  • 执行上下文包含变量环境、词法环境、this 绑定
  • 调用栈后进先出(LIFO)
  • var 提升值为 undefined,函数声明提升整个函数
  • 作用域链由词法作用域决定

📝 发现内容有误?点击此处直接编辑

← 上一篇 JavaScript 引擎架构
下一篇 → JavaScript 编译与解释执行
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库