javascript - 在 Node.js 上使用 Proxy.apply() 不起作用。这是一个错误还是我做错了?

标签 javascript node.js proxy call apply

我正在使用 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
};

访问ab 都应被代理的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];
  }
});

Demo on jsfiddle

您不会获得该函数的结果,因为这需要您执行它。

注意:可以将它与 一起使用,并且效果很好。唯一需要注意的是,您的代理也将捕获所有内部函数。为了防止记录数十个 valueOf,我强烈建议使用 like this isNative function 来测试函数是否是 native 函数。

关于javascript - 在 Node.js 上使用 Proxy.apply() 不起作用。这是一个错误还是我做错了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37646677/

相关文章:

linux - 如何使用不同的导出 IP 一次运行多个 Tor 进程?

python - 更改 IP 地址 Python Selenium

javascript - removeAttr ('id' )清除#id,但点击仍然有效

javascript - 修改或覆盖material-ui按钮css

node.js - 子标准输出设置为 "inherit"和 "onData"监听器

node.js - 如何 mock Mongoose ?

androidviewclient - 无法通过端口转发连接到虚拟机上的设备

javascript - 捕获后如何重试?

javascript - 有没有办法在一行中根据要求创建一个新的 Node 对象?

node.js - 有或没有 token JWT+PASSPORT 可用的路线