JavaScript中变量查找依赖静态创建的作用域链,即函数定义时确定的词法环境嵌套链;查找时从当前执行上下文逐级向上搜索至全局,未找到则抛ReferenceError;闭包因[[Environment]]持久引用外层环境而实现。

JavaScript 中变量查找依赖作用域链,它是一条由多个词法作用域(Lexical Environment)按嵌套顺序连接而成的单向链表。当访问一个变量时,引擎从当前执行上下文的词法环境开始,逐级向上查找,直到全局环境;若全程未找到,则报 ReferenceError。
作用域链的形成时机:函数定义时确定
作用域链不是在调用时动态拼接的,而是在函数被创建(即解析并生成函数对象)时,就静态地记录了其外层词法环境的引用。这个“外层”取决于函数在源码中**书写的位置**,而非调用位置。
- 每个函数对象内部都保存着一个 [[Environment]] 内部属性,指向其定义时所处的词法环境
- 该词法环境又通过其 outer 引用指向更外层的词法环境,如此构成链式结构
- 最顶层是全局词法环境,其 outer 为
null
变量查找过程:从内到外逐层搜索
当执行函数、遇到一个自由变量(即未在当前作用域声明的变量)时,JavaScript 引擎按以下步骤查找:
- 先在当前执行上下文的词法环境(即当前函数的 LexicalEnvironment)中查找该变量的绑定(binding)
- 若未找到,继续在其 outer 引用指向的上一级词法环境中查找
- 重复此过程,沿作用域链向上遍历,直到全局环境
- 若全局环境也未找到,抛出
ReferenceError: xxx is not defined
注意:查找只看变量是否被声明(var、let、const、函数声明等),不关心是否已赋值;对 let/const 还会触发暂时性死区(TDZ)检查。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
闭包是作用域链的自然结果
当一个嵌套函数被返回或传递到外部作用域后仍能访问其定义时的外层变量,正是因为它的 [[Environment]] 始终持有对外层词法环境的引用——作用域链被保留下来,不会因外层函数执行结束而销毁。
- 例如:内层函数引用了外层函数的局部变量,即使外层函数已 return,该变量仍保留在内存中(只要内层函数还存在)
- 多个嵌套层级对应多级 outer 链接,如 A 函数内定义 B,B 内定义 C,则 C 的作用域链为:C → B → A → 全局
可通过 console.dir 查看部分线索(非标准但实用)
虽然无法直接读取函数的 [[Environment]],但在 Chrome / Edge 等浏览器中,用 console.dir(fn) 可看到 [[Scopes]] 字段(开发者工具专用),显示当前函数的作用域链快照,包括 Closure、Script、Global 等类型,直观反映变量可访问范围。
这有助于调试“为什么这里能访问那个变量”或“为什么修改了却没生效”这类问题。

















