js实现切面
在JavaScript中实现切面编程(AOP)可以通过多种方式实现,以下是常见的几种方法:
使用高阶函数
通过高阶函数包装原函数,在调用前后插入逻辑:

function wrapFunction(originalFn, beforeFn, afterFn) {
return function(...args) {
beforeFn && beforeFn.apply(this, args);
const result = originalFn.apply(this, args);
afterFn && afterFn.apply(this, args);
return result;
};
}
const original = () => console.log('原始函数');
const wrapped = wrapFunction(
original,
() => console.log('调用前'),
() => console.log('调用后')
);
wrapped();
使用Proxy对象
ES6的Proxy可以拦截对象操作,实现更细粒度的AOP:

const target = {
doSomething: () => console.log('原始操作')
};
const handler = {
get(target, prop) {
if (prop === 'doSomething') {
return function(...args) {
console.log('前置拦截');
const result = target[prop].apply(target, args);
console.log('后置拦截');
return result;
};
}
return target[prop];
}
};
const proxy = new Proxy(target, handler);
proxy.doSomething();
修改原型方法
对于类或构造函数,可以通过修改原型实现AOP:
class MyClass {
method() {
console.log('原始方法');
}
}
const original = MyClass.prototype.method;
MyClass.prototype.method = function() {
console.log('前置增强');
original.apply(this, arguments);
console.log('后置增强');
};
new MyClass().method();
使用装饰器(需要Babel或TypeScript)
ES7装饰器语法提供更简洁的AOP实现:
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;
}
}
new Example().add(2, 3);
注意事项
- 原型方法修改会影响所有实例
- Proxy性能开销高于直接调用
- 装饰器目前仍是实验性语法
- 异步函数需要特殊处理(如使用async/await包装)
这些方法可以根据具体需求选择,高阶函数和Proxy适合函数级别的切面,装饰器更适合类方法的切面增强。






