javascript变量查找依赖函数定义时确定的静态作用域链,即从当前词法环境逐级向上遍历outer引用直至全局环境;闭包因保留对外层词法环境的引用而使变量不被回收;全局环境为链终点,严格模式下未声明赋值会报错。

JavaScript 中变量的查找依赖作用域链(Scope Chain),它是一条由多个词法环境(Lexical Environment)组成的单向链表,从当前执行上下文开始,逐级向上查找,直到全局环境。这个过程不是运行时动态“搜索”,而是函数定义时就确定了其外层词法环境的引用关系。
作用域链在函数创建时就已确定
每个函数对象内部都保存着一个 [[Environment]] 内部属性,指向其定义时所处的词法环境。这个引用不会因为函数在哪里被调用而改变——这就是“词法作用域”的核心。
- 例如,嵌套函数 inner 在 outer 内部定义,inner 的 [[Environment]] 就指向 outer 执行时创建的词法环境(含 outer 的变量)
- 即使把 inner 函数返回并赋值给全局变量,再在全局中调用,它依然沿用创建时绑定的 outer 环境,而非调用时的全局环境
查找过程:从当前环境开始,逐级向上遍历
当访问一个变量(如 foo)时,引擎按以下顺序查找:
- 先在当前执行上下文的词法环境(即当前函数的 LexicalEnvironment)中找
foo - 没找到,就去该环境的 outer 引用(即 [[Environment]] 指向的上层环境)中找
- 继续向上,直到全局词法环境;若仍找不到,抛出
ReferenceError
注意:这个“outer”不是调用栈,也不是 this 或 call/apply 改变的对象,而是函数定义时静态确定的词法嵌套关系。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
闭包是作用域链的直观体现
当内层函数引用了外层函数的变量,并且该内层函数在外部被保留(如作为返回值、事件回调等),外层变量就不会被回收——因为作用域链仍持有对其词法环境的引用。
function createCounter() {
let count = 0;
return function() {
count++; // 这里访问的是 createCounter 执行时创建的词法环境中的 count
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
每次调用 createCounter() 都会生成新的词法环境,counter 函数的作用域链就包含那个专属的环境,因此能持续访问并修改其中的 count。
全局变量是作用域链的终点
全局环境没有 outer 引用(为 null),所以它是链的末端。所有未声明就直接赋值的变量(非严格模式下)会自动挂到全局对象(如 window 或 globalThis)上,从而可被任何作用域链最终访问到——但这属于隐式全局,应避免。
- 严格模式下对未声明变量赋值会直接报错,不创建全局变量
- 可通过
globalThis显式访问全局对象,但不推荐用于普通变量管理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










