在防抖(或节流)里"再传自定义参数"有两种常见场景,分别对应两种写法:
场景 1
浏览器事件本身已经带参数(如 event
),但我还想额外塞几个自己的值。
场景 2
我不是在 DOM 事件里用,而是手动调用 debounce 返回的函数,并希望像普通函数一样任意传参。
下面把两种场景都拆开讲,并给出"拿来即用"的代码模板。
================================================ 一、场景 1:DOM 事件 + 自定义参数
思路
- 把自定义参数先"绑"到函数上;
- 让防抖包装器合并
bind
传进来的参数 与 浏览器给出的event
; - 按顺序一起交给真正的回调。
代码模板(支持多参 + 事件对象)
js
/**
* 支持自定义参数的防抖工厂
* @param fn 真正要执行的函数
* @param delay 延迟毫秒
* @returns 新的防抖函数
*/
function debounce(fn, delay) {
let timer = null;
// 注意:返回的函数可能被 bind 过,所以参数个数不固定
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args); // args 里既有 bind 的,也有浏览器给的 event
}, delay);
};
}
/* ========== 使用示例 ========== */
function search(keyword, type, e) { // 自定义参数在前,事件对象在最后
console.log('关键词:', keyword);
console.log('类型:', type);
console.log('事件对象:', e.type); // e 是浏览器原生的 input 事件
}
const $input = document.querySelector('#search');
// 1. 用 bind 把自定义参数"预置"进去
const handler = debounce(search.bind(null, '手机', 'electronics'), 500);
// 2. 监听事件;浏览器会把 event 追加到 bind 参数后面
$input.addEventListener('input', handler);
运行结果(输入一次字符,停止 500ms 后):
makefile
关键词: 手机
类型: electronics
事件对象: input
要点
bind
的参数量任意,浏览器会把event
追加到末尾;- 你的真正回调只要按 bind 顺序声明形参即可;
- 不需要改防抖逻辑,因为
args
已经天然是"合并后"的数组。
================================================ 二、场景 2:手动调用,与 DOM 无关
思路
把防抖函数当成普通函数用,想传什么就传什么。
此时不需要 bind,直接调用即可,防抖内部会把所有实参缓存到定时器。
代码模板
js
function debounce(fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
/* ========== 业务函数 ========== */
function save(id, content, author) {
console.log(`保存文章 id=${id}, 作者=${author}, 内容前20字=${content.slice(0, 20)}`);
}
/* ========== 生成防抖版本 ========== */
const debounceSave = debounce(save, 1000);
/* ========== 任意地方手动调用 ========== */
debounceSave(1024, '前端防抖与节流详解......', '张三');
debounceSave(1024, '前端防抖与节流详解......(已修改)', '李四');
// 1 秒后只会打出最后一次
输出(1 秒后):
ini
保存文章 id=1024, 作者=李四, 内容前20字=前端防抖与节流详解......(已修改)
================================================ 三、一张表总结
用法 | 自定义参数位置 | 事件对象是否同时存在 | 实现手段 |
---|---|---|---|
DOM 事件 | 任意 | ✅ 在最后 | search.bind(null, a, b) |
手动调用 | 任意 | ❌ | debounceSave(a, b, c) |