javascript中作用域链在函数定义时形成,基于词法作用域沿[[environment]]逐级向上查找变量;闭包使外部变量因内部函数的环境引用而持久化。

JavaScript 中通过作用域链查找外部函数变量,本质是沿着当前执行上下文的 词法作用域 一层层向上搜索,直到找到变量声明或抵达全局作用域。
作用域链的形成时机
函数在定义时(不是执行时),JS 引擎就根据其书写位置确定了它能访问哪些外部变量。这个“嵌套关系”被记录在函数的内部属性 [[Environment]] 中,构成一条链式结构——这就是作用域链的源头。
- 每个函数对象创建时,都绑定一个词法环境(Lexical Environment)引用,指向其外层函数的词法环境(或全局环境)
- 执行函数时,会基于该
[[Environment]]创建自己的词法环境,并将其作为作用域链的起点 - 变量查找从当前词法环境开始,没找到就顺着
outer引用跳到上一级,依次类推
查找过程:从内到外逐级匹配
当代码中引用一个变量(比如 count),引擎按以下顺序查找:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先查当前函数的词法环境(含参数、
let/const声明、function声明) - 没找到,就查该函数的
[[Environment]]指向的外层词法环境 - 继续向上,直到全局词法环境;若仍不存在,则抛出
ReferenceError
例如:
function outer() {let x = 10;
function inner() {
console.log(x); // 查找 x:inner 环境 → outer 环境 → 找到
}
inner();
}
闭包让作用域链“活下来”
即使外部函数已执行完毕,只要内部函数还存在(如被返回或被赋值给变量),它的 [[Environment]] 依然保留对外部词法环境的引用,因此变量不会被回收。
- 这是闭包的核心机制:内部函数“记住”并持续访问其定义时的作用域链
- 多次调用同一个外部函数,每次生成的内部函数拥有各自独立的作用域链(对应不同的外层变量实例)
注意:只看定义位置,不看调用位置
作用域链完全由函数在哪里定义决定,和它在哪里调用无关。哪怕把内部函数传给另一个函数执行,它仍然沿用定义时的外层环境。
function createCounter() {let count = 0;
return function() { return ++count; };
}
const inc = createCounter();
inc(); // 1 —— 访问的是 createCounter 内部那次执行时产生的 count
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










