Якщо я правильно розумію, кожен об'єкт у Javascript успадковується від прототипу Object
Це може здатися розщепленням волосся, але є різниця між javascript (загальним терміном для реалізації ECMAScript) та ECMAScript (мовою, що використовується для реалізації javascript). Саме ECMAScript визначає схему успадкування, а не javascript, тому лише власні об’єкти ECMAScript повинні реалізовувати цю схему успадкування.
Запущена програма javascript складається щонайменше із вбудованих об’єктів ECMAScript (об’єкт, функція, число тощо) та, можливо, деяких власних об’єктів (наприклад, функцій). Також можуть бути деякі хост-об'єкти (наприклад, DOM-об’єкти у браузері або інші об'єкти в інших середовищах хоста).
Хоча вбудовані та власні об'єкти повинні реалізовувати схему успадкування, визначену в ECMA-262, хост-об'єкти цього не виконують. Тому не всі об'єкти в середовищі javascript повинні успадковувати від Object.prototype . Наприклад, хост-об'єкти в IE, реалізовані як об'єкти ActiveX, видаватимуть помилки, якщо їх розглядатимуть як власні об'єкти (отже, чому try..catch використовується для ініціалізації об'єктів MS XMLHttpRequest). Деякі об'єкти DOM (наприклад, NodeLists в IE в режимі примх), якщо передані методам Array, будуть видаляти помилки, DOM-об'єкти в IE 8 і нижче не мають схеми успадкування, подібної ECMAScript тощо.
Тому не слід вважати, що всі об'єкти в середовищі javascript успадковуються від Object.prototype.
що означає, що кожен об'єкт у Javascript має доступ до функції hasOwnProperty через ланцюг прототипу
Що не відповідає правилам певних об'єктів хостингу в IE в режимі примх (і IE 8 і нижче завжди).
З огляду на вищесказане, варто задуматися, чому об’єкт може мати власний метод hasOwnProperty та доцільність виклику замість нього іншого методу hasOwnProperty, не попередньо перевіряючи, чи це гарна ідея чи ні.
Редагувати
Я підозрюю, що причиною використання Object.prototype.hasOwnProperty.call
є те, що в деяких браузерах хост-об’єкти не мають методу hasOwnProperty , використовуючи виклик, а вбудований метод є альтернативою. Однак робити це загалом не здається гарною ідеєю з причин, зазначених вище.
Що стосується хост-об'єктів, оператор in може бути використаний для перевірки властивостей, наприклад
var o = document.getElementsByTagName('foo');
// false in most browsers, throws an error in IE 6, and probably 7 and 8
o.hasOwnProperty('bar');
// false in all browsers
('bar' in o);
// false (in all browsers? Do some throw errors?)
Object.prototype.hasOwnProperty.call(o, 'bar');
Альтернатива (перевірена в IE6 та інших):
function ownProp(o, prop) {
if ('hasOwnProperty' in o) {
return o.hasOwnProperty(prop);
} else {
return Object.prototype.hasOwnProperty.call(o, prop);
}
}
Таким чином, ви тільки викликуєте вбудовану hasOwnProperty там, де у об'єкта його немає (успадковане чи інше).
Однак якщо об’єкт не має hasOwnProperty
методу, він, мабуть, так само підходить використовувати оператор in, оскільки, ймовірно, об’єкт не має схеми успадкування, і всі властивості є на об'єкті (хоча це лише припущення), наприклад в операторі є поширеним (і, здавалося б, успішним) способом тестування підтримки DOM-об'єктів для властивостей.