当尝试在未定义的对象上调用方法时,有没有办法使JavaScript无声地失败?

时间:2012-03-09 14:41:55

标签: javascript oop error-handling undefined

我不想检查某个对象是否被定义,而是希望能够简单地在其上调用一个方法,并且如果该对象实际上是未定义的,则让它无声地失败。所以,而不是必须写下以下内容:

if(obj.delegate && obj.delegate.closeMenu){
    obj.delegate.closeMenu();
}

我可以在if语句中写下这一行:obj.delegate.closeMenu()。如果obj没有委托属性,则不会发生任何事情。如果delegate确实存在,但它没有closeMenu()方法,则相同。

这可能吗?如果是,请提供实施。

5 个答案:

答案 0 :(得分:5)

目前没有可靠的方法可以做到这一点,而无需编写更多代码。您可以使用try - catch,例如:

try {
  obj.delegate.closeMenu();
} catch(e) {
  // fail silently
}

请注意,非标准__noSuchMethod__可以满足您的需求,但并不是所有地方都支持。


更新:在ES6中,您可以使用代理执行类似操作。例如:

function getProperty(target, name, receiver) {
  if (name in target) {
    return target[name];
  }
  // property does not exist
  var result = doSomethingElse();
  return result;
}

var object = return Proxy(something, {
  'get': getProperty
});

答案 1 :(得分:2)

您可以稍微缩短代码......

if((obj.delegate||{}).closeMenu){
    obj.delegate.closeMenu();
}

或者甚至喜欢这个......

var noop = function(){}; // keep a noop function handy

 // then use it like this...
((obj.delegate||{}).closeMenu||noop)()

...虽然您将把closeMenu的调用上下文更改为全局(或严格的undefined),这可能不是必需的。仍然认为你可能会觉得它很有趣。

答案 2 :(得分:0)

我就是这样做的:

var delegate = obj.delegate;

if ( !delegate ) {

    // handle the case that there is no delegate object

} else {

    // work with delegate here
    delegate.closeMenu();    

}

答案 3 :(得分:0)

不,如您所述,这是不可能的。正如Mathias建议的那样,一个很好的赌注是try { } catch { }。或者,您可以将委托设置为存根对象,如下所示:

if(obj.delegate === undefined) obj.delegate = { closeMenu:function(){} }
obj.delegate.closeMenu();

答案 4 :(得分:0)

或者你可以使用精彩的underscore库并写一些荒谬的东西,如:

_(_(obj).has('delegate')).has('closeWindow') && obj.delegate.closeWindow()

打字不多,但更紧凑......