PHP的__call
魔术方法相当于什么?
给我的印象是Proxy可以做到,但不能做到。
class MyClass{
constructor(){
return new Proxy(this, {
apply: function(target, thisArg, args){
console.log('call', thisArg, args);
return 'test';
},
get: function(target, prop){
console.log('get', prop, arguments);
}
});
}
}
var inst = new MyClass();
console.log(inst.foo(123));
get
似乎可以正常工作,因为我看到“ get foo”,但是apply
无效。我得到的不是函数错误。
答案 0 :(得分:2)
apply
实际上处理对对象本身的函数调用 ,即,如果您执行new Proxy(someFunction, { apply: ... })
,则apply
将在someFunction
被调用之前被调用叫。
没有任何东西可以捕获对属性的调用,因为这将是多余的– get
已经在返回属性时进行处理。您可以简单地返回一个函数,该函数在被调用时会产生一些调试输出。
class MyClass{
constructor(){
return new Proxy(this, {
get: function(target, prop) {
return function() {
console.log('function call', prop, arguments);
return 42;
};
}
});
}
}
var inst = new MyClass();
console.log(inst.foo(123));
答案 1 :(得分:1)
是的代理服务器可以做到这一点,但是即使在捕获方法时,也必须使用代理服务器的get
。
然后在这里我也执行您的真实方法,但是我不知道您是否要模拟它。
class MyClass {
constructor() {
return new Proxy(this, {
get(target, prop, receiver) {
if (typeof target[prop] !== "function") {
return "etcetcetc";
}
return function(...args) {
console.log('call', args);
return target[prop]();
};
}
});
}
foo() {
console.log('I am foo!');
}
}
var inst = new MyClass();
inst.foo(123);
如您所见,如果您正在调用实例的方法,我将对其进行拦截,然后返回原始方法执行。
如果您正在访问实例的属性,我将始终返回一个模拟字符串。
然后当然要用您想要的行为对其进行更改。
答案 2 :(得分:1)
这是实现您所要求的另一种方式。
class MyClass{
constructor(){
return new Proxy(this, {
get(target, propKey, receiver) {
const origMethod = target[propKey];
return function (...args) {
let result = origMethod.apply(this, args);
console.log(propKey + JSON.stringify(args)
+ ' -> ' + JSON.stringify(result));
return result;
};
}
});
}
foo = (x) => {
return x + 1;
};
}
var inst = new MyClass();
console.log(inst.foo(123));