我当前有一个 Proxy 对象,如果未定义属性,我想捕获对该属性的调用。我的代码的基本版本是这样的。
var a = new Proxy({}, {
get: function(target, name, receiver) {
if (target in name) {
return target[name];
} else {
function a() {
return arguments;
}
var args = a();
return [target, name, receiver, args];
}
}
});
Run Code Online (Sandbox Code Playgroud)
对此处(即:a.b; a.c()等)的属性调用应返回属性调用的目标、名称、接收者和参数。
然而,我希望解决的问题需要我知道属性调用是针对属性还是函数,以便我可以对每个属性进行不同的处理。检查参数对象的长度不起作用,因为调用a.c()会产生 0 的长度,就像 一样a.b,因此它将被视为普通属性而不是方法。
因此,有没有办法确定尝试访问的属性是否被作为函数调用。
更新:我应该澄清,如果访问的属性/方法未定义且存在,则此方法需要工作。
这可以通过一种非常hacky的方式实现。如果属性是 ,我们返回一个函数undefined。如果调用此函数,则我们知道用户试图将该属性作为函数调用。如果不是,则将其称为财产。为了检查该函数是否被调用,我们利用了Promise在事件循环的下一次迭代中调用 a 的回调这一事实。这意味着我们直到稍后才知道它是否是一个属性,因为用户需要有机会首先调用该函数(因为我们的代码是一个 getter)。
undefined此方法的一个缺点是,如果用户期望属性,则从对象返回的值将是新函数,而不是。此外,如果您立即需要结果并且不能等到下一次事件循环迭代,那么这对您不起作用。
const obj = {
func: undefined,
realFunc: () => "Real Func Called",
prop: undefined,
realProp: true
};
const handlers = {
get: (target, name) => {
const prop = target[name];
if (prop != null) { return prop; }
let isProp = true;
Promise.resolve().then(() => {
if (isProp) {
console.log(`Undefined ${name} is Prop`)
} else {
console.log(`Undefined ${name} is Func`);
}
});
return new Proxy(()=>{}, {
get: handlers.get,
apply: () => {
isProp = false;
return new Proxy(()=>{}, handlers);
}
});
}
};
const proxied = new Proxy(obj, handlers);
let res = proxied.func();
res = proxied.func;
res = proxied.prop;
res = proxied.realFunc();
console.log(`realFunc: ${res}`);
res = proxied.realProp;
console.log(`realProp: ${res}`);
proxied.propC1.funcC2().propC3.funcC4().funcC5();Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3264 次 |
| 最近记录: |