1

有没有办法创建一个响应任何消息的对象?假设您有以下对象:

function Dog();
Dog.prototype.speak(){
   alert("woof woof");
}
var myDog = new Dog();

然后,当你这样做时,myDog.speak()你会收到一个警报"Woof woof"。但是我想要的是,当您调用myDog.jump()(未在类中定义)时,您将获得默认操作,例如向用户显示“您正在尝试执行不存在的方法”的警报。

你知道我该怎么做吗?

4

3 回答 3

3

简短的回答:你不能。

长答案:您可以使用__noSuchMethod__但它不是标准的,并且有一些计划将其删除,因为Proxy可以做同样的事情,甚至更多。另外,这是一个标准。因此,您可以使用代理来执行此操作,但出于性能原因,我不鼓励将所有对象都用作代理。

就个人而言,我只会让语言抛出它自己的异常,开发人员可以在错误控制台中检查。

于 2013-10-23T14:44:40.000 回答
1

没有基于标准的方法来做到这一点。最接近的是这个

你能得到的最接近的是:

function execute(obj, message, args) {
    if (obj[message] && typeof(message) === function) {
        obj[message].call(obj, args);
    } else {
       obj[message] = function() {
           //missing method functionality a la Ruby here
       };
    }
}
于 2013-10-23T14:38:46.370 回答
0

其他人已经提到了__noSuchMethod__Proxy,所以我将避免进一步详细介绍这些内容。

相反,我想强调另一种可以做你想做的事情的技术。请注意,这是一个丑陋的 hack,我不鼓励使用它,它甚至可能不适用于您的所有目标。考虑到这些注意事项,我向您介绍window.onerror

window.onerror = function(err) {
  if (/has no method/.test(err)) {
    console.log('oh my: ' + err) // This is where you'd call your callback
    return true
  }

  return false
}


;(function() {
  this.foo() // will be caught by window.onerror
})()

这 - 至少在我非常有限的测试中 - 捕获了 TypeErrors(至少在 Chrome 中,里程可能会有所不同),这表示无法找到该方法。以下是您不应该这样做的一些原因:

  • window.onerror只能有一个处理程序;如果您的处理程序被覆盖,这将不起作用
  • 它在全局范围内捕获 TypeErrors,而不仅仅是针对特定对象;即很多误报
  • 对于不知道在哪里找到这个处理程序的任何人来说,调试它会很有趣
  • 它紧密结合了依赖于这种行为的任何代码(坏、坏、坏!)

我不认为我可以足够强调你真的不应该考虑破解它。如果可以,请使用代理,如果不能,请承认失败。

于 2013-10-23T17:22:44.600 回答