JavaScript中变量通过作用域链查找外部变量,本质是从当前执行上下文的作用域逐级向上查找父级词法作用域直至全局作用域,该链在函数定义时静态确定,与调用位置无关。

JavaScript 中变量通过作用域链查找嵌套函数中的外部变量,本质是**从当前执行上下文的作用域开始,逐级向上查找父级词法作用域,直到全局作用域为止**。这个过程在函数定义时就已确定(静态/词法作用域),与函数在哪里调用无关。
作用域链的构建时机:定义时决定,而非调用时
当一个函数被定义时,JavaScript 引擎会将它内部的[[Environment]]内部属性绑定到其**外层词法环境**(即定义时所处的作用域)。这个绑定是静态的,不会因为函数 later 被传到别处调用而改变。
- 例如:内层函数即使作为返回值被带到全局调用,它仍能访问定义时的外层变量(闭包的核心)
- 作用域链是一条指向一系列词法环境(Lexical Environment)的只读链表,每个环境包含自己的变量对象(或声明绑定)和对上一级环境的引用
查找过程:从内到外,逐层匹配标识符
当代码中引用一个变量(如 count)时,引擎按以下顺序搜索:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先查当前函数的**局部词法环境**(含参数、let/const 声明、var 声明)
- 若未找到,继续查该函数[[Environment]]指向的**外层词法环境**(即定义它的那个函数或脚本环境)
- 重复此过程,直到到达全局环境(浏览器中是 window 或 globalThis)
- 如果全局也没找到,抛出 ReferenceError
常见易混淆点:作用域链 ≠ 调用栈
作用域链由函数定义位置决定;而调用栈反映函数执行顺序。二者独立:
立即学习“Java免费学习笔记(深入)”;
- var 声明会被提升并初始化为 undefined,但仍在当前作用域链中可查
- let/const 存在“暂时性死区”(TDZ),在声明前访问会报 ReferenceError,不是找不到,而是语法禁止访问
- 同名变量会“遮蔽”(shadow)外层变量:内层声明了 name,就不会再沿链向上找外层的 name
动手验证:用 console.dir 看闭包环境(仅限 V8)
在 Chrome DevTools 中调试时,可以打印函数查看其闭包:
- function outer() { const x = 10; return function inner() { return x; }; } const fn = outer(); console.dir(fn); // 展开 "Closure" 查看捕获的 x
- 注意:这不是标准 API,仅用于调试理解,生产中不可依赖

















