我正在使用 Proxy 来代理一个对象。 getter 和 setter 工作正常,符合预期。但是,永远不会调用 apply 方法。
var p = new Proxy({}, {
/* getter */
get(target, name) {
return target[name]
},
/* setter */
set(target, name, value) {
target[name] = value
},
/* supposedly called apply */
apply(target,that,arg) {
console.log('apply is called, what to do here?')
}
})
这样,我可以将某些东西分配给 p
或返回一些东西,即使它不存在。
例如,当我让 getter 函数返回这个时
get(target, name) {
return 'getting ' + name
},
然后 console.log(p.flappy)
我会得到响应“getting flappy”,即使它不存在。
到目前为止一切顺利,但是当我尝试通过 p.flapppy()
调用 flappy 时,它会抛出一个错误,指出 flappy 不是一个函数。
这仍然有些明显,因为 getter 不返回函数。当我让 getter 返回一个这样的函数时
get(target, name) {
return function() { return 'this is '+name }
},
我可以在属性不存在的情况下调用它。
console.log(
p.flappy() // this is flappy!
)
那么 apply 什么时候被调用?不在我刚刚在这里展示的片段中,在这种情况下也不在:
p.foo = function() {
console.log('yay!')
return 'foo!'
}
执行 p.foo()
或 p.foo.call()
或 p.foo.apply()
不起作用>,在这两种情况下都不会调用 apply。
此旅程的最终目的是我想根据属性是被读取还是被调用返回一个DIFFERENT 值。像这样:
p.someNewProperty // return what the getter function returns
p.anotherProperty() // return something else here because this is a function call
这可能吗?
最佳答案
我知道这个问题已经有一年了,但我也遇到了这个问题,我找到了一种方法来做你想做的事情。所以这是为了将来引用,因为我没有在其他地方找到正确的解决方案。
简短版本:访问对象(或类)内部的函数本质上是获取
具有该函数的对象的属性。诀窍是使用 apply
返回另一个 Proxy,这样您就可以正确地代理这些函数。
考虑以下对象:
const myObject = {
a: 'Hello world!',
b: x => x * x
};
访问a
或b
都应被代理的get
捕获,因为它们是对象的属性。您应该捕获所有 get
然后过滤函数。一旦你有了一个函数,你就会返回一个新的代理,它使用 Proxy.apply
捕获这个特定的函数。
然后,为了让函数按预期执行,在 Proxy.apply
中我们返回一个 Reflect.apply。 ,它按预期使用正确的参数调用原始函数。
您将得到以下代码:
const myProxyObject = new Proxy(myObject, {
get(target, propKey, receiver) {
// Calling functions
if (typeof target[propKey] === 'function') {
return new Proxy(target[propKey], {
apply(applyTarget, thisArg, args) {
console.log(`Calling ${thisArg.constructor.name}.${propKey}(${args})`);
return Reflect.apply(applyTarget, thisArg, args);
}
});
}
// Accessing properties
if (target.hasOwnProperty(propKey)) {
console.log(`Get value of ${target.constructor.name}.${propKey}`);
console.log(`Value: ${target[propKey]}`);
}
return target[propKey];
}
});
您不会获得该函数的结果,因为这需要您执行它。
注意:可以将它与类 一起使用,并且效果很好。唯一需要注意的是,您的代理也将捕获所有内部函数。为了防止记录数十个 valueOf
,我强烈建议使用 like this isNative function 来测试函数是否是 native 函数。
关于javascript - 在 Node.js 上使用 Proxy.apply() 不起作用。这是一个错误还是我做错了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37646677/