词法作用域指变量可见范围在代码编写阶段即已确定,由函数或块的嵌套位置决定,而非调用方式;引擎依据{}和函数定义构建静态作用域链,按书写层级向上查找变量,var限函数级、let/const限块级,闭包是其自然结果。

词法作用域指的是变量的可见范围,在代码写完、还没运行时就已经定死了——不是看函数怎么调用,而是看函数在哪儿写的。
变量在哪“出生”,就决定它能被谁“看见”
JavaScript 引擎在解析代码阶段(也就是词法分析时)就根据大括号 {} 和函数定义的嵌套结构,画出一张“作用域地图”。这张图一旦生成,就不会因为运行时的调用顺序改变。
- 全局里声明的变量,整份脚本都能看到
- 函数内部用 let/const 声明的变量,只在该函数的 {} 内有效
- 函数里再定义一个函数,内层函数天然“继承”外层函数的作用域,哪怕外层函数已经执行完了
作用域链是向上找,不是向外跳
当一个函数里引用某个变量,引擎不会查“谁调用了我”,而是按代码结构一层层往外找:先查自己作用域 → 找不到就查父级函数作用域 → 再找不到就查全局。这个查找路径就是作用域链,它完全由书写位置决定。
- 比如 inner() 在 outer() 里面定义,那它就能访问 outer 的变量,哪怕 inner 是从别的地方被调用的
- 如果把 inner 拿到 outer 外面定义,它就再也访问不到 outer 里的 let 变量了
var、let、const 的作用域边界不同
它们都遵循词法作用域,但“边界”划定方式不一样:
- var 只认函数边界:哪怕写在 if 或 for 里,也属于整个函数作用域
- let/const 认块级边界:只要被 {} 包住,就形成独立作用域,外面看不见
- 不加声明直接赋值(如 a = 10),会意外挂到全局,破坏词法隔离
闭包是词法作用域最自然的结果
函数带着它定义时所在环境的变量“一起走”,不是靠运行时记忆,而是靠编译阶段锁定的作用域链。所以即使外层函数执行结束,内层函数仍能读写那些变量——因为它们本就属于同一个词法层级。
- 这说明:变量能不能被访问,不取决于“函数还在不在执行”,而取决于“它写在哪儿”
- 这也是为什么用 let 在循环中创建函数,每个函数记住的是各自循环轮次的值——词法位置不同,绑定的变量实例就不同
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











