js 装饰器实现防抖
防抖装饰器的实现原理
防抖(Debounce)是一种常见的前端优化技术,用于限制函数在短时间内被频繁调用。装饰器(Decorator)是 JavaScript 的一种语法特性,可以方便地修改或增强函数的行为。
基础防抖装饰器实现
function debounce(delay) {
let timer = null;
return function(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
originalMethod.apply(this, args);
}, delay);
};
return descriptor;
};
}
使用示例
class SearchComponent {
@debounce(300)
handleSearch(query) {
console.log('Searching for:', query);
// 实际搜索逻辑
}
}
立即执行版本
有时需要第一次调用立即执行,后续调用才防抖:
function debounce(delay, immediate = false) {
let timer = null;
return function(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
if (immediate && !timer) {
originalMethod.apply(this, args);
}
clearTimeout(timer);
timer = setTimeout(() => {
if (!immediate) {
originalMethod.apply(this, args);
}
timer = null;
}, delay);
};
return descriptor;
};
}
取消功能扩展
为防抖函数添加取消能力:
function debounce(delay) {
let timer = null;
return function(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
originalMethod.apply(this, args);
}, delay);
};
// 添加取消方法
descriptor.value.cancel = function() {
clearTimeout(timer);
timer = null;
};
return descriptor;
};
}
TypeScript 版本实现
function debounce(delay: number): MethodDecorator {
return function(
target: Object,
propertyKey: string | symbol,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
let timer: number | null = null;
descriptor.value = function(...args: any[]) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
originalMethod.apply(this, args);
timer = null;
}, delay);
};
return descriptor;
};
}
注意事项
装饰器目前是 ECMAScript 的提案阶段特性,需要使用 Babel 插件 @babel/plugin-proposal-decorators 进行转译。在 TypeScript 中需要在 tsconfig.json 中启用 experimentalDecorators 选项。
防抖时间间隔需要根据实际场景调整,通常用户输入场景建议 300ms 左右,滚动事件可能更短。







