我有这样的代理处理程序:
let handler = {
get: function(target, name) {
let member = target[name];
if (typeof member === 'function') {
return function() {
//
}
}
return member;
}
}
只要在代理对象上调用方法:
var obj = {
foo: function() {
//
}
}
var p = new Proxy(obj, handler);
p.foo();
...它调用从handler
的getter返回的函数。但是问题是,当这样访问而不是调用这种方法时:
p.foo;
返回函数的整个定义。
有什么方法可以检查该方法是正在访问(p.foo
)还是被调用(p.foo()
)?我正在尝试实现以下目标:
if (typeof member === 'function' && member.isBeingCalled()) {
return function() {
//
}
}
另外,对于p.foo
,我想返回member
的定义,而不是处理程序的getter返回的函数。
答案 0 :(得分:0)
是的,这是可能的,但是为了使其起作用,您需要考虑调用方法时发生的事情
o.foo()
发生的事情比您想象的要多。
第一个操作是属性查找,它从对象"foo"
中检索具有键o
的属性的值。现在,检索到的值本身就是一个对象,特别是一个函数对象。
第二个操作是通过以下方式调用该函数作为方法
function.prototype.apply。这样做是通过将this
的值绑定到o
来调用函数。
因此,为了实现所需的行为,必须代理属性o.foo
的值,而不是o
本身的值。您的代理将使用Apply陷阱来拦截和修改该函数的调用,该属性的值是多少。 MDN对此进行了很好的描述。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply
基本上,您会写类似
const foo = o.foo;
const proxiedFoo = new Proxy(foo, {
apply(target, thisArg, argumentsList) {
if (thisArg) {
// this function is being invoked as a method
}
}
});
o.foo = proxiedFoo;