javascript中嵌套函数在定义时就构建作用域链,按从内到外顺序查找变量,直至全局;闭包是函数与其定义时作用域链的绑定,使内层函数能持续访问已执行完毕的外层变量。

JavaScript 中的嵌套函数会自动形成作用域链,查找变量时从当前作用域开始,逐级向上(向外)搜索,直到全局作用域为止。
作用域链的构建时机
函数在定义时(不是执行时),就确定了它的词法作用域,并记录下外层作用域的引用。这个“外层作用域的引用”就是作用域链的起点。
- 每个函数对象内部都有一个隐藏属性(如 [[Environment]]),指向其定义时所处的词法环境
- 嵌套越深,作用域链越长:内层函数 → 中层函数 → 外层函数 → 全局环境
- 即使外层函数已经执行结束、执行上下文被销毁,只要内层函数还存在(比如作为返回值或被闭包持有),它仍能访问原外层作用域中的变量
变量查找过程:从内到外线性扫描
当访问一个变量时,JS 引擎按以下顺序查找:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 先查当前函数的**活动对象(AO)或词法环境记录**(含参数、let/const 声明、function 声明)
- 没找到,就顺着 [[Environment]] 指针进入外层词法环境继续查
- 重复该过程,直到抵达全局环境(Global Environment)
- 若全局也找不到,抛出 ReferenceError
例如:
let x = 'global';
function outer() {
let x = 'outer';
function inner() {
let x = 'inner';
console.log(x); // 'inner' → 找到当前作用域
console.log(this.x); // undefined(非严格模式下 this 是 global,但 global 没有 x 属性)
}
inner();
}
块级作用域(let/const)如何融入作用域链
ES6 的块级声明不会创建新作用域链节点,但会在当前函数的词法环境中新增一个**块级环境记录(Block Environment Record)**,它作为当前函数环境的子级,仍属于同一作用域链层级。
- if、for、{} 中的 let/const 变量,存储在该块对应的环境记录中
- 查找时仍遵循作用域链:先查块级记录 → 再查函数级记录 → 再查外层函数…
- 因此 块不是独立的作用域链节点,而是函数词法环境内部的细分结构
闭包是作用域链的直观体现
当一个函数引用了其外部作用域中的变量,并被传出使用时,就形成了闭包——本质是函数与其对应作用域链的绑定。
- 返回的函数保留了对定义时外层变量的访问权,哪怕外层函数早已执行完毕
- 引擎必须维持那条完整的链,不能提前释放中间环境
- 这也是为什么多次调用外层函数会生成多个独立的作用域链副本(每个闭包持有一份自己的外层变量)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










