js aop实现
面向切面编程(AOP)在 JavaScript 中的实现
面向切面编程(AOP)是一种编程范式,用于将横切关注点(如日志、性能统计、安全控制等)从业务逻辑中分离出来。以下是几种在 JavaScript 中实现 AOP 的方法。
使用高阶函数
高阶函数是实现 AOP 的简单方式。通过包装目标函数,可以在其执行前后插入额外逻辑。
function wrap(targetFunc, beforeFunc, afterFunc) {
return function() {
beforeFunc.apply(this, arguments);
const result = targetFunc.apply(this, arguments);
afterFunc.apply(this, arguments);
return result;
};
}
// 示例
const originalFunc = () => console.log('Original function');
const beforeFunc = () => console.log('Before function');
const afterFunc = () => console.log('After function');
const wrappedFunc = wrap(originalFunc, beforeFunc, afterFunc);
wrappedFunc();
使用原型链扩展
通过修改 Function 原型,可以为所有函数添加 AOP 功能。
Function.prototype.before = function(beforeFunc) {
const targetFunc = this;
return function() {
beforeFunc.apply(this, arguments);
return targetFunc.apply(this, arguments);
};
};
Function.prototype.after = function(afterFunc) {
const targetFunc = this;
return function() {
const result = targetFunc.apply(this, arguments);
afterFunc.apply(this, arguments);
return result;
};
};
// 示例
const func = () => console.log('Original function');
const newFunc = func
.before(() => console.log('Before function'))
.after(() => console.log('After function'));
newFunc();
使用 ES6 Proxy
ES6 的 Proxy 可以拦截对象的操作,适合实现 AOP。
function createAOPProxy(target, beforeFunc, afterFunc) {
return new Proxy(target, {
apply: function(targetFunc, thisArg, args) {
beforeFunc.apply(thisArg, args);
const result = targetFunc.apply(thisArg, args);
afterFunc.apply(thisArg, args);
return result;
}
});
}
// 示例
const targetFunc = () => console.log('Original function');
const beforeFunc = () => console.log('Before function');
const afterFunc = () => console.log('After function');
const proxyFunc = createAOPProxy(targetFunc, beforeFunc, afterFunc);
proxyFunc();
使用装饰器(Decorator)
装饰器是 ES7 的提案,可以通过 @ 语法实现 AOP。
function log(target, name, descriptor) {
const originalMethod = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling ${name} with`, args);
const result = originalMethod.apply(this, args);
console.log(`Called ${name}, result:`, result);
return result;
};
return descriptor;
}
class Example {
@log
add(a, b) {
return a + b;
}
}
const example = new Example();
example.add(1, 2);
使用第三方库
一些第三方库(如 aspect.js 或 meld)提供了更完整的 AOP 支持。
// 使用 meld
const meld = require('meld');
const obj = {
foo: function() {
console.log('Original function');
}
};
meld.before(obj, 'foo', function() {
console.log('Before function');
});
meld.after(obj, 'foo', function() {
console.log('After function');
});
obj.foo();
总结
以上方法可以根据具体需求选择:

- 高阶函数适合简单场景。
- 原型链扩展适合全局 AOP。
- Proxy 适合需要精细控制的场景。
- 装饰器适合 ES7+ 项目。
- 第三方库适合复杂需求。






