js aop实现
在JavaScript中实现AOP(面向切面编程)
AOP的核心思想是将横切关注点(如日志、性能监控、事务管理等)从业务逻辑中分离出来,通过动态织入的方式实现模块化。以下是几种常见的实现方法:
使用函数装饰器模式
通过高阶函数对目标函数进行包装,实现前置/后置增强:

function logBefore(targetFunc) {
return function(...args) {
console.log(`调用 ${targetFunc.name},参数: ${args}`);
return targetFunc.apply(this, args);
};
}
const originalFunc = (a, b) => a + b;
const wrappedFunc = logBefore(originalFunc);
wrappedFunc(2, 3); // 输出日志后执行计算
原型链拦截方法
修改原型方法实现AOP拦截:

Function.prototype.before = function(beforeFn) {
const original = this;
return function(...args) {
beforeFn.apply(this, args);
return original.apply(this, args);
};
};
function sayHello() { console.log('Hello'); }
sayHello = sayHello.before(() => console.log('即将打招呼'));
sayHello(); // 先输出"即将打招呼",再输出"Hello"
使用ES6 Proxy
通过Proxy对象实现更精细的拦截控制:
const handler = {
apply: function(target, thisArg, args) {
console.log(`调用函数: ${target.name}`);
return target.apply(thisArg, args);
}
};
function sum(a, b) { return a + b; }
const proxy = new Proxy(sum, handler);
proxy(1, 2); // 输出日志后执行计算
基于AOP框架的实现
使用专用AOP库如aspect.js:
import { aspect, after } from 'aspect.js';
class LoggerAspect {
@after({
methodNamePattern: /.*/,
classNamePattern: /^SomeService/
})
logAfter(result, metadata) {
console.log(`方法 ${metadata.methodName} 执行完成`);
}
}
@aspect(new LoggerAspect())
class SomeService {
doWork() { /* ... */ }
}
实现注意事项
- 性能影响:频繁的代理和装饰可能带来性能开销,需在关键路径谨慎使用
- 上下文保持:确保增强函数与原函数共享相同的
this上下文 - 错误处理:建议在装饰器中添加try-catch块统一处理异常
- 执行顺序:多个切面时需明确优先级,可通过责任链模式控制
以上方法可根据具体场景选择使用,原型链方式和Proxy适合基础AOP需求,而专业框架提供更完善的切面管理能力。






