【问题标题】:Using ES6 Proxy results in any function call "is not a function"使用 ES6 代理会导致任何函数调用“不是函数”
【发布时间】:2017-09-18 17:20:15
【问题描述】:

我试图成为一个狡猾的开发人员,结果我迷失在 ES6 代理中。基本上,我想从我编写的另一个类中捕获属性中的任何获取或设置,并确保它们存储在对象之外的其他地方。它看起来像这样:

'use strict'
class MyObject()
{
    superAwesomeFunction(){//super awesome code goes here}
}

const myProxyObject = new Proxy(MyObject, {
get: function(target, name, receiver)
{
    if([CONDITIONS THAT MEET MY DEMANDS])
    {
         // deliver property values if they are
         // my super cool database (if they exist)
    }

    // else just ya know, forward it to the actual MyObject
    // property, if it's an actual property on MyObject
    return target[name];
},
set: function(target, name, value)
{
    if([CONDITIONS THAT MEET MY DEMANDS])
    {
         // set property values if they are
         // to super cool database
    }
    else
    {
        // just set the value to the property, which
        // gets created if it doesn't exist (WHICH IS SO COOL)
        target[name] = value;
    }
    return true;
}

好的,这很酷吗?你可以这样做:

// property that doesn't exist (yet)
console.log(myProxyObject.wholivesinapineappleunderthesea);

// but wait for it...
myProxyObject.wholivesinapineappleunderthesea = 'spongebob';

// bam! now it exists on the object, AND lives in my DB!
console.log(myProxyObject.wholivesinapineappleunderthesea);

其中,虽然为一些愚蠢的事情做了很多工作,但我无法解释这让我感到多么高兴。但是,这有一个问题。还记得我放在 MyObject() 中的 superAwesomeFunction() 吗?好吧,每当我现在尝试调用它时,ES6 都会让我感到悲伤:

myProxyObject.superAwesomeFunction 不是函数

ES6 坐在 LIES 的宝座上!它完全在那里,对吗?好的,所以我很确定我捕获了一些错误,因为当我调试时,我看到代理的 get 部分实际上正在接收 superAwesomeFunction 调用(这对于 superAwesomeFunction 来说是有意义的是一个包含函数的属性 (){})

这是我的问题: 有没有人知道任何解决方案可以让我保持可笑的动态属性并仍然调用我的 superAwesomeFunction()?是应用陷阱吗?

【问题讨论】:

  • 你需要做const myProxyObject = new Proxy(new MyObject(), {...})

标签: javascript node.js proxy ecmascript-6 es6-proxy


【解决方案1】:

这是一个小语法错误...您将代理包装在原始类周围,而不是对象。

试试:

const myProxyObject = new Proxy(new MyObject(), { ... });

这应该没问题。例如:

> class Blah {
... run() {
..... console.log('yay')
..... }
... }
[Function: blah]
> myProx = new Proxy(new Blah(), {});
blah {}
> myProx.run()
yay

【讨论】:

    【解决方案2】:

    延伸山姆的回答。

    以下成功:

    function Foo() {
      this.bar = function() { console.log('baz'); }
    }
    let foo = new Proxy(new Foo(), {});
    foo.bar();

    但是,当get 陷阱添加到处理程序时,会抛出“不是函数”:

    function Foo() {
      this.bar = function() { console.log('baz'); }
    }
    let foo = new Proxy(new Foo(), {
      get: function(target, prop) {}
    });
    foo.bar();

    这里的解决方案是添加typeof检查目标现有功能的默认处理:

    function Foo() {
      this.bar = function() { console.log('baz'); }
    }
    let foo = new Proxy(new Foo(), {
      get: function(target, prop) {
        if (typeof target[prop] === 'function') {
          return target[prop].bind(target);
        }
      }
    });
    foo.bar();

    以下文章提供了更多示例并提供了与代理处理程序一起使用的漂亮样板:Safely Extending The JavaScript Set Object Using Proxies

    【讨论】:

      【解决方案3】:

      完整的答案代码在这里,谢谢大家!

      'use strict'
      class MyObject()
      {
          superAwesomeFunction(){
              console.log("this works!");
          }
      }
      
      const myProxyObject = new Proxy( new MyObject(), {
      get: function(target, name, receiver)
      {
          if([CONDITIONS THAT MEET MY DEMANDS])
          {
              // do something cool for yourself
          }
      
          return target[name];
      },
      set: function(target, name, value)
      {
          if([CONDITIONS THAT MEET MY DEMANDS])
          {
              // do something cool for yourself
          }
          else
          {
              // just set the value to the property, which
              // gets created if it doesn't exist (WHICH IS SO COOL)
              target[name] = value;
          }
          return true;
      }
      });
      

      【讨论】:

        猜你喜欢
        • 2014-12-05
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-27
        • 2023-03-20
        • 2015-03-29
        相关资源
        最近更新 更多