作用域链是函数定义时由嵌套词法环境通过outer引用逐级连接形成的静态查找路径,决定变量访问位置、可达性及具体值;它自当前词法环境向上查找直至全局,与调用位置无关,是闭包、循环中异步问题等现象的根本原因。
JavaScript作用域链是一条由多个执行上下文的作用域按嵌套顺序连接而成的查找路径,它决定了变量和函数在代码中**从哪里被访问、能否被访问、以及访问到的是哪个值**。
每当函数被调用,JS引擎就会为其创建一个执行上下文(Execution Context),其中包含自己的词法环境(Lexical Environment)。这个环境内部保存了该函数定义时所在的作用域信息,并通过 outer 引用指向其外层词法环境——层层向上,直到全局环境。这一串引用关系就构成了作用域链。
当访问一个变量(比如 console.log(x)),JS引擎会沿着当前执行上下文的词法环境
开始查找:
例如:
function outer() {
let x = 'outer';
function inner() {
console.log(x); // 找不到自己的x → 查outer环境 → 找到'outer'
}
inner();
}
outer();
因为作用域链在函数定义时就固定,所以内部函数即使在外部调用,也能访问定义时的外层变量——这就是闭包的核心机制。
作用域链只管 标识符(变量名、函数名)的解析;而 this 是运行时基于调用方式动态确定的,两者机制完全不同。不要以为“能访问变量”就代表“this 指向那里”。
基本上就这些。理解作用域链不是背概念,关键是明白“定义位置决定查找路径”,很多看似奇怪的行为——比如闭包、for 循环中 setTimeout 输出相同值、模块私有变量——背后都是它在起作用。