在Ruby中,您可以捕获对缺少的方法的调用,并在运行中定义它。
我想在JavaScript中完成的是拥有一个没有方法的对象。我希望将一个缺少的方法转换为对emit()的调用:
app.isReady() -> app.emit("isReady")
soldier.kills() -> soldier.emit("kills")
我认为最好捕获丢失的方法错误并运行emit(methodName),而不是在运行时定义所有方法(来自固定列表)。这样,如果对象有数百或数千个事件,我们就没有性能开销。
这样做的最佳方式是什么?
更新:这是一个API设计,所以我宁愿远离:
try {
app.isReady()
} catch(e) {
...
}
我想知道如何在幕后完成此操作,以便用户可以像往常一样使用方法。
答案 0 :(得分:6)
这样,如果对象有数百/数千个事件,我们就没有性能开销。
我认为将方法添加到对象的性能开销小于将方法调用转换为emit调用的性能开销是一个巨大的误解。
但是,您无法在ES5中实现此功能
然而,可以使用Harmony proxies实现此目的。
我建议查看simulating __noSuchMethod__
。
我相信ES6代理是实验性的,可以在V8中打开,所以今天你可以将它们与node.js一起使用。
答案 1 :(得分:2)
在此阶段不可能始终如一地执行此操作,除非您可以保证您的应用只能在Mozilla上运行,在这种情况下noSuchMethod就是您所追求的。
据我所知,其他浏览器都没有实现这一点。
答案 2 :(得分:0)
使用以下过程在函数指针上使用RegExp test
:
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")
你可能会问为什么你想要使用下标符号。下标表示法允许动态创建属性和方法。因此,如果您进行任何类型的元编程,您很可能会使用下标符号。
<强>参考强>
答案 3 :(得分:0)
我已经创建了一个Node.js包来处理你的情况。它被称为auto-object。
以下是一瞥:
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"
更重要的是,这也适用于班级。