Javascript 中缺少捕获方法并执行一些逻辑?

发布于 2024-12-18 03:12:52 字数 468 浏览 3 评论 0 原文

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

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

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

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

最好的方法是什么?

更新:这是一个 API 设计,所以我宁愿不参与:

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

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

In Ruby, you can capture a call to a method which is missing and define it on the fly.

What I wanna accomplish in JavaScript is to have an object with no methods. I want a missing method to be translated into a call to emit():

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

I think it's better to capture the missing method error and run emit(methodName) rather than defining all methods (from a fixed list) at runtime. That way we don't have performance overhead if there are hundreds or thousands of events for an object.

What is the best way to do this?

UPDATE: This is an API design so I rather stay out of:

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

I want to know how I can accomplish this behind the scenes so the users can use methods as usual.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

洒一地阳光 2024-12-25 03:12:52

这样,如果一个对象有数百/数千个事件,我们就不会产生性能开销。

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

但是,您无法在 ES5 中实现此功能,

但是可以使用 Harmony 代理 来实现此功能。

我建议查看模拟__noSuchMethod__

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

In that way we don't have a performance overhead if there are hundreds/thousands of events for an object.

I think it's a massive misconception to think the performance overhead of adding methods to an object is smaller then the performance overhead of converting method invocations into emit calls.

However you cannot implement this feature in ES5

One could however implement this using Harmony proxies.

I recommend looking at simulating __noSuchMethod__.

I believe ES6 proxies are experimental and can be turned on in V8 so you could use them with node.js today.

傾城如夢未必闌珊 2024-12-25 03:12:52

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

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

It's not possible to do that consistently at this stage, unless you can guarantee your app will only run on Mozilla, in which case noSuchMethod is what you're after.

As far as I know, none of the other browsers implement this yet.

入画浅相思 2024-12-25 03:12:52

通过以下过程在函数指针上使用 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")

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

参考资料

Use a RegExp test on the function pointer by using the following process:

  • pass the object literal as an argument
  • pass the name of the default method as a string
  • pass the name of the fallback method as a string
  • using subscript notation to dereference the function pointer
  • use a regexp to check the type against the name function
  • if it succeeds, call the default using subscript notation
  • if it fails, call the fallback using subscript notation

For example:

/* 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")

You might ask why you'd ever want to use subscript notation. Subscript notation allows for dynamic creation of properties and methods. So if you ever do any sort of metaprogramming, you'll most likely be using the subscript notation.

References

゛清羽墨安 2024-12-25 03:12:52

我创建了一个 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" 

此外,这也适用于课堂。

I've create a Node.js package to deal with your situation. It's called auto-object.

Here's a glance:

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" 

What's more, this works with class too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文