
当使用 let 声明函数并传入 setTimeout 后再重新赋值该变量,setTimeout 仍执行原始函数体——因为回调函数在 setTimeout 调用时已被按值捕获(即引用已确定),后续变量重赋值不影响已注册的异步任务。
当使用 let 声明函数并传入 settimeout 后再重新赋值该变量,settimeout 仍执行原始函数体——因为回调函数在 settimeout 调用时已被**按值捕获(即引用已确定)**,后续变量重赋值不影响已注册的异步任务。
在 JavaScript 中,setTimeout(fn, delay) 的行为关键在于:它立即接收并保存对 fn 当前值的引用,而非在定时器触发时动态读取变量名对应的最新值。来看原代码:
let foo = function() {
console.log(1);
};
setTimeout(foo, 1000); // 此刻 foo 指向打印 1 的函数,该引用被 setTimeout 内部保存
foo = function() {
console.log(2);
}; // 此赋值仅改变变量 foo 的指向,不影响已注册的 setTimeout 回调
✅ 输出为 1 是完全符合预期的:setTimeout 在调用时获取的是 foo 当时所引用的函数对象(内存地址),之后无论 foo 变量被重新赋值为何种函数,都不影响该已排队任务的执行逻辑。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
⚠️ 注意事项:
- let 允许重新赋值(区别于 const),但变量重赋值 ≠ 函数重定义;它只是让标识符指向新函数对象,旧函数对象若仍有引用(如被 setTimeout 持有),依然有效。
- 若希望延迟执行新函数,需在 setTimeout 调用前完成赋值,或改用闭包/箭头函数动态捕获,例如:
let foo = () => console.log(1); setTimeout(() => foo(), 1000); // 此时 foo 是动态读取的,输出为 2(因 foo 已被重赋值) foo = () => console.log(2);
? 总结:setTimeout 注册的是函数引用快照,不是变量名的“实时绑定”。理解这一机制,有助于避免异步编程中因变量覆盖导致的逻辑偏差。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










