闭包实现节流的核心是让lasttime变量私有且持久:外层函数定义lasttime=0,返回的内层函数持续读写它,确保多次调用间状态隔离、不重置、无全局依赖,时间判断基于now-lasttime>=delay。

用闭包记录上次执行时间戳,本质是把 lastTime 变量“锁”在函数内部,让它跨多次调用持续存在、不被重置、也不被外部干扰。
闭包让 lastTime 真正属于自己
每次调用 throttle(fn, delay),都应该生成一个独立的执行环境。闭包确保这个环境里的 lastTime 是私有的:
- 外层函数定义
let lastTime = 0,只在这个实例中可见 - 返回的节流函数每次读取并更新它,不需要传参、也不依赖全局变量
- 两个滚动监听器分别调用
throttle,它们的lastTime完全隔离,互不影响
时间戳版节流的核心判断逻辑
关键不是“设个 delay”,而是用当前时间与 lastTime 做差值判断是否满足间隔:
- 触发时获取
Date.now() - 若
now - lastTime >= delay,才执行目标函数,并立刻更新lastTime = now - 否则直接跳过,不执行也不设定时器
为什么不能用普通变量或 this 绑定?
普通局部变量每次调用都会重新初始化;this 在事件回调中容易丢失或指向错误对象;而闭包中的 lastTime:
- 生命周期由内层函数持有,只要节流函数还在使用,它就一直存在
- 不受事件回调上下文影响,
lastTime的读写始终稳定 - 组件卸载后,只要节流函数被回收,
lastTime也会自然释放,无内存泄漏风险
简单可运行的时间戳版实现
这段代码直接体现闭包如何管理 lastTime:
let lastTime = 0;
return function (...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}
它没用定时器、不依赖外部状态,靠闭包稳稳托住 lastTime,每次调用都基于自己那一份“时间记忆”做决策。











