Как определить, имеет ли собственный объект JavaScript свойство/метод?

Я думал, что это будет так же просто, как:

if(typeof(Array.push) == 'undefined'){
  //not defined, prototype a version of the push method
  // Firefox never gets here, but IE/Safari/Chrome/etc. do, even though
  // the Array object has a push method!
}

И он отлично работает в Firefox, но не в IE, Chrome, Safari, Opera, они возвращают все свойства/методы собственного объекта Array как «неопределенные», используя это контрольная работа.

Метод .hasOwnProperty( prop ) работает только с экземплярами... поэтому он не работает, но методом проб и ошибок я заметил, что это работает.

//this works in Firefox/IE(6,7,8)/Chrome/Safari/Opera
if(typeof(Array().push) == 'undefined'){
  //not defined, prototype a version of the push method
}

Есть ли что-то неправильное в использовании этого синтаксиса для определения того, существует ли свойство/метод в Native Object / ~"JavaScript Class"~, или есть лучший способ сделать это?


person scunliffe    schedule 27.02.2009    source источник


Ответы (4)


Во-первых, typeof — это оператор, а не функция, поэтому скобки не нужны. Во-вторых, получить доступ к прототипу объекта.

alert( typeof Array.prototype.push );
alert( typeof Array.prototype.foo );

Когда вы выполняете typeof Array.push, вы проверяете, имеет ли сам объект Array метод push, а не экземпляры Array имеют метод push.

person Peter Bailey    schedule 27.02.2009
comment
Интересно... Я читал, что .prototype предназначен только для добавления новых свойств/методов к объектам, я не думал использовать для него typeof. например прототип devguru.com/technologies/JavaScript/10764.asp typeof devguru.com/technologies/JavaScript/11529.asp - person scunliffe; 27.02.2009
comment
Именно для этого, да, но не ТОЛЬКО для этого. Я рекомендую посмотреть презентацию Дугласа Крокфорда по Advanced Javascript в YUI Theater (developer.yahoo.com/yui/theater) — там есть кое-что интересное, в том числе то, как работают прототипы объектов. - person Peter Bailey; 27.02.2009
comment
это не увидит свойства, определенные в родительских прототипах - person Vitaly Kushner; 01.12.2011
comment
Это не будет работать со всеми случаями. Например, (typeof XMLHttpRequest.prototype.onload !== 'undefined') выдает ошибку TypeError: недопустимый вызов. Правильный способ: («загрузить» в XMLHttpRequest.prototype) - person Maciej Krawczyk; 19.03.2017

Правильный способ проверить, существует ли свойство:

if ('property' in objectVar)
person Barney    schedule 21.03.2010
comment
Я искал способ проверить, существует ли «AddFavorite» в window.external, пока это: alert («AddFavorite» в window.external); единственный работающий скрипт! спасибо - person Elmer; 04.11.2010
comment
Это должен быть принятый ответ, он работает во всех случаях, в отличие от текущего принятого ответа. - person Maciej Krawczyk; 19.03.2017
comment
В моем случае это работает, только если я использую это так: "prop" in ObjectClass.prototype, но не когда "prop" in ObjectClass - person XCanG; 07.03.2021

Доступ к .hasOwnProperty можно получить в прототипе массива, если typeof недостаточно идиоматичен.


if (Array.prototype.hasOwnProperty('push')) {
    // Native array has push property
}

person ryan v    schedule 19.04.2010
comment
хороший вариант - просто нужно убедиться, что это не тестируется на элементах DOM в более старых версиях IE без предварительной проверки, имеет ли объект метод .hasOwnProperty() msdn.microsoft.com/en-us/library/ - person scunliffe; 20.04.2010

И в файрфоксе нормально работает

Вот только случайно! Обычно вы не можете ожидать, что метод прототипа также будет существовать в функции-конструкторе.

if(typeof(Array().push) == 'undefined')

Это было почти правильно, за исключением того, что вы забыли new, извечную ловушку JavaScript. new Array().push или [].push для краткости правильно проверит, что экземпляр имеет нужный вам метод.

person bobince    schedule 27.02.2009