js实现函数监听
函数监听的基本方法
在JavaScript中,可以通过多种方式实现函数监听,主要包括原生事件监听、自定义事件和函数包装等。以下是几种常见的实现方式:
使用addEventListener
适用于DOM元素的事件监听,例如点击、键盘输入等:
document.getElementById('myButton').addEventListener('click', function() {
console.log('Button clicked');
});
自定义事件监听
通过EventTarget接口创建自定义事件,适用于非DOM对象的监听:
const eventTarget = new EventTarget();
eventTarget.addEventListener('customEvent', (e) => {
console.log('Custom event triggered', e.detail);
});
// 触发事件
eventTarget.dispatchEvent(new CustomEvent('customEvent', { detail: { data: 'example' } }));
函数包装监听
通过高阶函数包装原函数,在调用前后执行监听逻辑:
function originalFunction() {
console.log('Original function executed');
}
function withListener(fn, before, after) {
return function() {
before && before();
const result = fn.apply(this, arguments);
after && after();
return result;
};
}
const wrappedFunction = withListener(
originalFunction,
() => console.log('Before execution'),
() => console.log('After execution')
);
wrappedFunction();
Proxy代理监听
使用ES6的Proxy对象监听函数调用:
const targetFunction = function() {
console.log('Target function called');
};
const proxiedFunction = new Proxy(targetFunction, {
apply: function(target, thisArg, argumentsList) {
console.log('Function is about to be called');
const result = target.apply(thisArg, argumentsList);
console.log('Function has been called');
return result;
}
});
proxiedFunction();
发布-订阅模式
实现一个简单的发布-订阅系统,适用于多个监听器的情况:
class EventEmitter {
constructor() {
this.events = {};
}
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(listener => listener(...args));
}
}
}
const emitter = new EventEmitter();
emitter.on('functionCalled', () => console.log('Function was called'));
emitter.emit('functionCalled');
注意事项
- 对于DOM事件监听,记得在适当的时候使用removeEventListener移除监听,避免内存泄漏
- Proxy方法在性能要求高的场景可能需要谨慎使用
- 发布-订阅模式适合组件间通信或复杂的事件系统
- 函数包装方式会改变原函数的引用,可能影响其他依赖该引用的代码







