js aop实现
在JavaScript中实现AOP(面向切面编程)
AOP是一种编程范式,允许在不修改原有代码的情况下,通过“切面”动态添加功能。以下是几种常见的实现方式:
使用高阶函数包装
通过函数包装在目标函数执行前后插入逻辑:
function wrap(targetFunc, beforeFunc, afterFunc) {
return function() {
beforeFunc && beforeFunc.apply(this, arguments);
const result = targetFunc.apply(this, arguments);
afterFunc && afterFunc.apply(this, arguments);
return result;
};
}
// 示例用法
const originalFunc = () => console.log('原始函数');
const loggedFunc = wrap(
originalFunc,
() => console.log('调用前'),
() => console.log('调用后')
);
原型链扩展
通过修改Function原型实现AOP:
Function.prototype.before = function(beforeFn) {
const self = this;
return function() {
beforeFn.apply(this, arguments);
return self.apply(this, arguments);
};
};
Function.prototype.after = function(afterFn) {
const self = this;
return function() {
const result = self.apply(this, arguments);
afterFn.apply(this, arguments);
return result;
};
};
// 示例用法
const func = () => console.log('主要功能');
const enhancedFunc = func
.before(() => console.log('前置处理'))
.after(() => console.log('后置处理'));
ES6 Proxy实现
利用Proxy对象拦截目标操作:
function createAopProxy(target, { before, after }) {
return new Proxy(target, {
apply(target, thisArg, args) {
before && before.apply(thisArg, args);
const result = Reflect.apply(target, thisArg, args);
after && after.apply(thisArg, args);
return result;
}
});
}
// 示例用法
const original = (x) => x * 2;
const proxy = createAopProxy(original, {
before: () => console.log('计算开始'),
after: () => console.log('计算结束')
});
装饰器实现(需要Babel转译)
使用ES7装饰器语法:
function log(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console.log(`调用 ${name} 参数: ${args}`);
const result = original.apply(this, args);
console.log(`调用 ${name} 结果: ${result}`);
return result;
};
return descriptor;
}
class Example {
@log
add(a, b) {
return a + b;
}
}
面向对象的AOP实现
创建专门的AOP工具类:
class Aop {
static before(target, method, advice) {
const original = target[method];
target[method] = function() {
advice.apply(this, arguments);
return original.apply(this, arguments);
};
}
static after(target, method, advice) {
const original = target[method];
target[method] = function() {
const result = original.apply(this, arguments);
advice.apply(this, arguments);
return result;
};
}
}
// 示例用法
const obj = { greet: name => `Hello ${name}` };
Aop.before(obj, 'greet', name => console.log(`即将问候 ${name}`));
Aop.after(obj, 'greet', () => console.log('问候完成'));
选择哪种实现方式取决于具体需求和技术栈。高阶函数和原型链方式兼容性最好,Proxy方式更现代但需要ES6支持,装饰器语法需要编译转换但最符合未来标准。







