javascript中嵌套函数访问外层变量靠的是定义时的作用域链,而非调用位置;查找时从自身词法环境开始,逐级向上至外层函数、块级作用域,最终到全局,同名变量会遮蔽但不覆盖外层变量。

JavaScript 中嵌套函数能访问外层变量,靠的不是“调用时在哪”,而是“定义时写在哪”。只要函数在某个作用域内定义,它的作用域链就固定了,查找变量时会严格按这条链一层层往上找。
查找路径由定义位置决定
函数内部访问一个变量,引擎不会看它被谁调用、在哪执行,只看它写在哪个作用域里。这个位置决定了它的“父级环境”是谁。
- 如果 inner 函数直接写在全局里,它查变量就只走:自身 → 全局
- 如果 inner 写在 outer 函数内部,那它的链就是:自身 → outer → 全局
- 哪怕把 inner 函数作为返回值传出去、在别处调用,这条链也不会变
查找过程是逐级回溯的
引擎从当前函数自己的词法环境开始查,没找到就跳到上一级,再没找到继续跳,直到全局;一旦命中同名变量就停止,不会继续往上。
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
- 先查当前函数内部声明的变量(包括参数、let/const/var)
- 再查外层函数的变量(比如 outer 函数体内的 let x = 10)
- 最后查全局变量(挂在 window 或 globalThis 上的)
- 中间任何一级有同名变量,就会“遮蔽”外层的,但不会覆盖或删除它
块级作用域也参与链式查找
ES6 的 if、for、{} 块,只要用了 let 或 const,就构成一个独立的作用域节点,也会被纳入作用域链。
- 比如在 if (true) { let x = 2; } 里定义的 inner 函数,能访问这个 x
- 因为 inner 的定义位置在该块内,它的上一级环境就是这个块级环境
- var 不创建块级作用域,所以不会形成新链节点
闭包让外层变量“活下来”
当嵌套函数被返回或传到外部使用,它仍保留对定义时外层环境的引用。这意味着外层变量即使函数执行结束也不会被回收。
- 函数定义时,它的 [[Environment]] 内部属性已绑定好外层词法环境
- 调用时新建的执行上下文,其词法环境的 outer 指针指向的就是这个固定环境
- 这就是为什么
function outer() { let x = 1; return () => x; }()还能读到 x
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










