js 实现aop
在 JavaScript 中实现 AOP(面向切面编程)
AOP 是一种编程范式,允许开发者将横切关注点(如日志、性能监控、事务管理等)从业务逻辑中分离出来。以下是几种在 JavaScript 中实现 AOP 的方法:
使用高阶函数
通过高阶函数包裹目标函数,可以在调用前后注入逻辑。
function wrap(targetFn, beforeFn, afterFn) {
return function(...args) {
if (beforeFn) beforeFn.apply(this, args);
const result = targetFn.apply(this, args);
if (afterFn) afterFn.apply(this, args);
return result;
};
}
const originalFn = () => console.log('业务逻辑');
const wrappedFn = wrap(originalFn,
() => console.log('调用前逻辑'),
() => console.log('调用后逻辑')
);
wrappedFn();
使用 ES6 Proxy
Proxy 可以拦截对象操作,非常适合实现 AOP。
const createAopProxy = (target, { before, after }) => {
return new Proxy(target, {
apply: (target, thisArg, args) => {
if (before) before.apply(thisArg, args);
const result = target.apply(thisArg, args);
if (after) after.apply(thisArg, args);
return result;
}
});
};
const fn = () => console.log('业务逻辑');
const proxiedFn = createAopProxy(fn, {
before: () => console.log('前置通知'),
after: () => console.log('后置通知')
});
proxiedFn();
使用装饰器(Decorator)
在支持 ES7 装饰器的环境中,可以用装饰器语法实现 AOP。
function log(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console.log(`调用 ${name} 方法`);
return original.apply(this, args);
};
return descriptor;
}
class Service {
@log
doSomething() {
console.log('执行业务逻辑');
}
}
new Service().doSomething();
使用 AOP 库
现有库如 aspect.js 提供了更完整的 AOP 支持。
import { before, after } from 'aspect.js';
class Service {
@before(() => console.log('方法调用前'))
@after(() => console.log('方法调用后'))
doSomething() {
console.log('执行业务逻辑');
}
}
new Service().doSomething();
选择建议
- 简单场景使用高阶函数或 Proxy
- TypeScript/ES7 项目推荐使用装饰器
- 复杂需求考虑专用 AOP 库
每种方法都能有效分离关注点,选择取决于项目环境和技术栈。







