确定 Proxy 对象中的 get handler 是否正在处理函数调用

dbr*_*dbr 5 javascript

我当前有一个 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,因此它将被视为普通属性而不是方法。

因此,有没有办法确定尝试访问的属性是否被作为函数调用。

更新:我应该澄清,如果访问的属性/方法未定义且存在,则此方法需要工作。

quw*_*quw 3

这可以通过一种非常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)