我有一个类,我想应用代理,观察方法调用和构造函数调用:
Calculator.js
class Calc {
constructor(){}
add(a, b) {
return a+b;
}
minus(a, b) {
return a-b;
}
}
module.exports = Calc;
index.js
const Calculator = require('./src/Calculator');
const CalculatorLogger = {
construct: function(target, args, newTarget) {
console.log('Object instantiated');
return new target(...args);
},
apply: function(target, thisArg, argumentsList) {
console.log('Method called');
}
}
const LoggedCalculator = new Proxy(Calculator, CalculatorLogger);
const calculator = new LoggedCalculator();
console.log(calculator.add(1,2));
当调用它时,我希望输出为:
对象实例化
名为
的方法
然而,apply没有被调用,我认为这是因为我将Proxy附加到Calculator类,而不是实例化的对象,所以不知道apply
陷阱。 / p>
如何在方法调用和构造函数调用上构建一个包含所有代理的“观察”。
答案 0 :(得分:4)
我认为这是因为我将Proxy附加到Calculator类,而不是实例化对象,所以不知道apply trap。
你是完全正确的,代理操作对象,所以除非调用Calculator
类的函数属性,否则它不会调用apply,如下所示:
class Calculator {
constructor() {
this.x = 1;
}
instanceFunction() {
console.log('Instance function called');
}
static staticFun() {
console.log('Static Function called');
}
}
const calcHandler = {
construct(target, args) {
console.log('Calculator constructor called');
return new target(...args);
},
apply: function(target, thisArg, argumentsList) {
console.log('Function called');
return target(...argumentsList);
}
};
Calculator = new Proxy(Calculator, calcHandler);
Calculator.staticFun();
const obj = new Calculator();
obj.instanceFunction();
有了这个清楚,用代理包装Calculator
实例的方法可能是:
construct
上的实例:
const CalculatorInstanceHandler = {
apply(target, thisArg, args) {
console.log('Function called');
return target(...args);
}
}
const CalculatorClassHandler = {
construct(target, args) {
const instance = new target(...args);
return new Proxy(instance, CalculatorInstanceHandler);
}
}
Calculator
课程中设置工厂功能,以便创建代理实例:
const CalculatorInstanceHandler = {
apply(target, thisArg, args) {
return target(...args);
}
};
class Calculator {
static getNewCalculator() {
const instance = new Calculator();
return new Proxy(instance, CalculatorInstanceHandler);
}
}
答案 1 :(得分:1)
不要在类上使用handler.apply()
,而是修改handler.construct()
返回的内容,而不是向其中添加代理。
class originalClass {
constructor() {
this.c = 1;
}
add(a, b) {
return a + b + this.c;
}
}
const proxiedClass = new Proxy(originalClass, {
construct(target, args) {
console.log("constructor of originalClass called.");
return new Proxy(new target(...args), {
get(target, prop, receiver) {
console.log(prop + " accessed on an instance of originalClass");
const val = target[prop];
if (typeof target[prop] === "function") {
console.log(prop + " was a function");
return function(...args) {
console.log(prop + "() called");
return val.apply(this, args);
};
} else {
return val;
}
}
});
}
});
const proxiedInstance = new proxiedClass();
console.log(proxiedInstance.add(1, 2));

这里有2个代理: