JavaScript变量查找严格按静态作用域链进行:先查当前块级作用域(let/const),再逐级向上搜索函数作用域直至全局,未找到则抛ReferenceError;var因提升和函数作用域易引发混乱,应禁用。

核心是理解作用域链如何查找变量,而不是靠记忆“不能重名”。只要清楚当前变量在哪个作用域被绑定、是否被遮蔽、能否访问到外部同名变量,混乱自然消失。
看懂作用域链的查找顺序
JavaScript 每次读取一个变量时,会从当前执行位置开始,按以下顺序向上查找:
- 先找当前块(如 if、for、{} 内)里用 let/const 声明的同名变量
- 没找到就往外一层函数作用域找(包括形参)
- 再没找到就继续向上,直到全局作用域
- 全程找不到才报 ReferenceError
这个过程是静态确定的——写代码时就定死了,不依赖运行时状态。所以不用猜“它到底用了哪个”,直接顺着嵌套结构往上看就行。
识别并接受合法的变量遮蔽
let/const 允许在内层重新声明同名变量,这不是 bug,是设计好的遮蔽(shadowing):
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 合法且安全:外部 let x = 10,内部 let x = 20 —— 两个 x 完全独立,内部修改不影响外部
- 需注意可读性:如果内外都叫 x,但语义不同(比如一个是用户 ID,一个是临时计数器),建议改名,如 userId 和 retryCount
- 禁止操作:函数形参是绑定,不能再用 let 声明同名变量,否则 SyntaxError
彻底避开 var 带来的干扰
var 的函数作用域 + 变量提升,是逻辑混乱的主要源头:
- 循环中用 var i,所有异步回调共享同一个 i,导致输出全是终值
- console.log(x) 在 var x = 5 前执行,得到 undefined 而非报错
- 同一作用域多次 var x 不报错,但行为难预测
现代项目应禁用 var。ESLint 规则 no-var 可强制执行,替换为 let 或 const 即可消除大部分隐患。
多人协作时用命名空间隔离全局污染
当必须暴露到全局(如插件、SDK),避免直接挂 window 属性:
- 用唯一对象做命名空间:MyApp.utils.formatDate()、MyApp.api.fetchUser()
- 模块化优先:用 ES Module 导出,让打包工具处理作用域,不手动挂全局
- 立即执行函数(IIFE)已过时,仅在无构建环境的老项目中作为兜底
不复杂但容易忽略

















