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

function withLogging(fn) {
return function(...args) {
console.log(`Entering ${fn.name}`);
const result = fn.apply(this, args);
console.log(`Exiting ${fn.name}`);
return result;
};
}
function sayHello(name) {
console.log(`Hello, ${name}`);
}
const wrappedSayHello = withLogging(sayHello);
wrappedSayHello("World");
使用ES7装饰器
在支持装饰器的环境中(如Babel或TypeScript),可以直接修饰方法:

function log(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling ${name} with`, args);
return original.apply(this, args);
};
return descriptor;
}
class MyClass {
@log
greet(name) {
console.log(`Hello ${name}`);
}
}
使用Proxy对象
通过Proxy拦截对象操作:
const handler = {
get(target, prop, receiver) {
const original = target[prop];
if (typeof original === 'function') {
return function(...args) {
console.log(`Before ${prop}`);
const result = original.apply(this, args);
console.log(`After ${prop}`);
return result;
};
}
return original;
}
};
const obj = {
sayHi(name) {
console.log(`Hi ${name}`);
}
};
const proxied = new Proxy(obj, handler);
proxied.sayHi('Proxy');
修改原型方法
直接修改Function原型实现AOP:
Function.prototype.before = function(beforeFn) {
return (...args) => {
beforeFn.apply(this, args);
return this.apply(this, args);
};
};
Function.prototype.after = function(afterFn) {
return (...args) => {
const result = this.apply(this, args);
afterFn.apply(this, args);
return result;
};
};
function test() {
console.log('test');
}
test.before(() => console.log('before')).after(() => console.log('after'))();
这些方法各有适用场景:高阶函数适合简单函数包装,装饰器适合类方法,Proxy适合复杂对象拦截,原型修改则会影响所有函数。选择时需考虑项目环境和需求。






