Есть ли способ заставить JavaScript молча сбоить при попытке вызвать метод для неопределенного объекта? - PullRequest
2 голосов
/ 09 марта 2012

Вместо того, чтобы проверять, определен ли объект или нет, я хотел бы иметь возможность просто вызвать для него метод и заставить его молчать, если объект на самом деле не определен. Таким образом, вместо того, чтобы писать следующее:

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

Я мог бы просто написать строку внутри оператора if: obj.delegate.closeMenu(). Если obj не имеет делегированного свойства, просто ничего не произойдет. То же самое, если delegate существует, но у него нет метода closeMenu().

Возможно ли это? Если это так, пожалуйста, предложите реализацию.

Ответы [ 5 ]

5 голосов
/ 09 марта 2012

В настоящее время нет надежного способа сделать это без написания дополнительного кода.Вы можете использовать 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
});
2 голосов
/ 09 марта 2012

Вы могли бы немного сократить свой код следующим образом ...

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 в строгом), что, вероятно, нежелательно.Все еще думал, что вы могли бы найти это интересным.

0 голосов
/ 09 марта 2012

Или вы можете использовать замечательную библиотеку underscore и написать что-то смешное, например:

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

Не намного меньше печатать, но более компактно ...

0 голосов
/ 09 марта 2012

Нет, это невозможно, как вы описали. Хорошая ставка - try { } catch { }, как предложил Матиас. Кроме того, вы можете установить делегат для заглушки, как показано ниже:

if(obj.delegate === undefined) obj.delegate = { closeMenu:function(){} }
obj.delegate.closeMenu();
0 голосов
/ 09 марта 2012

Вот как бы я это сделал:

var delegate = obj.delegate;

if ( !delegate ) {

    // handle the case that there is no delegate object

} else {

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

}
...