真正造成问题的是var声明+变量提升+闭包引用的组合,应改用let/const、iife传参、箭头函数参数固化及严格模式避免隐式全局。

函数作用域本身不会“污染”,真正造成问题的是 var 声明 + 变量提升 + 闭包引用 的组合,尤其在回调函数中表现明显。关键不是避免“函数作用域”,而是控制变量声明方式和作用域边界,让每个回调拿到它该有的值。
用 let/const 替代 var 声明循环变量
var 声明的变量会被提升到函数顶部,且整个循环共用一个绑定;而 let 在每次迭代中创建**新的绑定**,每个回调捕获的是各自迭代时的独立变量。
- ❌ 错误写法(var + 回调):所有回调打印的都是最终 i 值(如 5)
- ✅ 正确写法(let):每个回调拿到对应索引,i 是块级绑定,每次循环都新建
把回调逻辑封装进立即执行函数(IIFE)
在 ES6 之前常用方案:用自执行函数把当前 i 值作为参数传入,形成独立作用域。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 给回调函数传参,而非依赖外部变量
- 参数是值传递,不会随外层 i 改变而改变
- 适用于需兼容老环境或处理复杂逻辑的场景
用箭头函数配合解构或参数默认值固化上下文
箭头函数不绑定自己的 this,但更重要的是——它天然不创建新作用域,因此要靠外层 let 绑定或显式传参来隔离数据。
- 在事件监听、定时器、Promise.then 中,优先用 (item, index) => { ... } 形式直接接收数据
- 避免在回调里读取循环变量,改从参数或闭包参数中取值
- 例如:menus.forEach((menu, i) => menu.addEventListener('click', () => console.log(i)))
警惕隐式全局与未声明变量
函数内不加 let/const/var 直接赋值,会意外挂到 window 上,所有回调共享同一全局变量。
- 比如写成
counter = 0而非let counter = 0 - 这种变量不属于函数作用域,也不受块级限制,极易被其他回调篡改
- 开启严格模式('use strict')可自动报错,强制声明
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










