4

在 Ruby 中,您可以捕获对缺少的方法的调用并动态定义它。

我想在 JavaScript 中完成的是拥有一个没有方法的对象。我希望将缺少的方法转换为对 emit() 的调用:

app.isReady() -> app.emit("isReady")
soldier.kills() -> soldier.emit("kills")

我认为最好捕获缺少的方法错误并运行 emit(methodName) 而不是在运行时定义所有方法(来自固定列表)。这样,如果一个对象有成百上千个事件,我们就不会有性能开销。

做这个的最好方式是什么?

更新:这是一个 API 设计,所以我宁愿远离:

try {
  app.isReady()
} catch(e) {
  ...
}

我想知道如何在幕后完成此操作,以便用户可以照常使用方法。

4

4 回答 4

6

这样,如果一个对象有成百上千的事件,我们就不会有性能开销。

我认为认为向对象添加方法的性能开销小于将​​方法调用转换为发出调用的性能开销是一个巨大的误解。

但是你不能在 ES5 中实现这个特性

然而,人们可以使用Harmony 代理来实现这一点。

我建议看模拟__noSuchMethod__.

我相信 ES6 代理是实验性的,可以在 V8 中启用,因此您现在可以将它们与 node.js 一起使用。

于 2011-11-27T03:53:27.450 回答
2

在这个阶段不可能始终如一地做到这一点,除非你可以保证你的应用程序只能在 Mozilla 上运行,在这种情况下noSuchMethod就是你所追求的。

据我所知,其他浏览器都没有实现这一点。

于 2011-11-27T03:52:27.683 回答
0

test通过使用以下过程在函数指针上使用 RegExp :

  • 将对象文字作为参数传递
  • 将默认方法的名称作为字符串传递
  • 将回退方法的名称作为字符串传递
  • 使用下标表示法取消引用函数指针
  • 使用正则表达式根据名称检查类型function
  • 如果成功,则使用下标表示法调用默认值
  • 如果失败,则使用下标表示法调用回退

例如:

/* Define mapping */
var app = {"emit": emit};

/* Define interface */
function emit(){}

function \u1000missing(object, method, fallback)
  {
  /* Existence check */
  if (/function/.test(object[method]) ) 
    {
    object[method]();
    }
  /* reify */
  else
    {
    object[fallback](method)
    }    
  }

\u1000missing(app,"isReady","emit")

您可能会问为什么要使用下标表示法。下标符号允许动态创建属性和方法。因此,如果您曾经进行任何类型的元编程,您很可能会使用下标符号。

参考

于 2014-04-04T19:31:00.500 回答
0

我创建了一个 Node.js 包来处理您的情况。它被称为自动对象

这是一瞥:

const myObject = autoObject.createObject(function(name) {
    if(name.startsWith("say")) {
        return function() {
            return name.substr(3);
        }
    }

    return name;
});

myObject.foo;       ///< "foo" 
myObject.sayFoo();  ///< "Foo" 
myObject.sayBar();  ///< "Bar" 

更重要的是,这也适用于类。

于 2017-06-17T12:57:19.953 回答