我正在尝试为我的课程构建一个AOP记录器...我遇到一个问题,当我重新回到目标函数时,该函数将无法访问this
所以我的AOP有点像这样
AOP.js
class AOP {
constructor() {
}
static ClassHandler(obj) {
const InstanceHandler = {
get(target, prop, receiver) {
console.log(target.constructor.name);
const origMethod = target[prop];
return function (...args) {
// let result = Reflect.apply(origMethod, this, args)
let result = Reflect.get(target, prop, receiver)
result = Reflect.apply(result, this, args);
console.log(prop + JSON.stringify(args)
+ ' -> ' + JSON.stringify(result));
return result;
};
},
apply(target, thisArg, argumentsList) {
console.log('actually applied');
}
}
const handler = {
construct(target, args) {
console.log(`${target.name} instantiated`);
console.log(args);
const instance = Reflect.construct(...arguments);
return new Proxy(instance, InstanceHandler);
}
}
return new Proxy(obj, handler);
}
}
module.exports = AOP;
单身人士
OtherClass.js
class OtherClass {
constructor() {
this._blah = 'this is a shoutout';
}
shoutOut() {
console.log(this._blah);
}
}
module.exports = new OtherClass();
和一个需要单例的类
CalculatorDI.js
class Calculator {
constructor(otherClass) {
this.otherClass = otherClass;
}
add(a, b) {
this.otherClass.shoutOut();
return a+b;
}
minus(a, b) {
return a-b;
}
}
module.exports = Calculator;
像这样将它们放在一起:
const AOP = require('./src/aspects/AOP');
const Calculator = AOP.ClassHandler(require('./src/CalculatorDI'));
const otherClass = require('./src/OtherClass');
const calculator = new Calculator(otherClass);
calculator.add(1,1);
运行此命令时,出现错误:
TypeError:this.otherClass.shoutOut不是函数
答案 0 :(得分:1)
您的问题是您的代理始终会为访问的任何属性(包括this.otherClass
)返回一个函数。您将需要使用
const instanceHandler = {
get(target, prop, receiver) {
console.log(target.constructor.name);
const orig = Reflect.get(target, prop, receiver);
if (typeof orig == "function") {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
return function (...args) {
const result = orig.apply(this, args);
console.log(prop + JSON.stringify(args) + ' -> ' + JSON.stringify(result));
return result;
};
} else {
return orig;
}
}
};
还请注意,apply
中不需要instanceHandler
陷阱,因为您的实例都不是函数。