Есть ли практическая разница [между моими примерами]?
У пользователя может быть объект JavaScript, созданный с помощью Object.create(null)
, который будет иметь null
[[Prototype]]
цепочку и, следовательно, не будет hasOwnProperty()
доступен в нем. По этой причине использование второй формы не сработает.
Это также более безопасная ссылка на Object.prototype.hasOwnProperty()
(и более короткая).
Вы можете представить, что кто-то мог сделать ...
var someObject = {
hasOwnProperty: function(lol) {
return true;
}
};
Что привело бы к hasProp(someObject)
сбою, если бы он был реализован, как ваш второй пример (он нашел бы этот метод непосредственно на объекте и вызвал бы его, а не делегировал Object.prototype.hasOwnProperty
).
Но менее вероятно, что кто-то переопределит Object.prototype.hasOwnProperty
ссылку.
И раз уж мы находимся, зачем мы вообще определяем эту функцию?
См. Выше.
Это просто вопрос ярлыков и локального кеширования доступа к свойствам для (небольшого) увеличения производительности ...
Теоретически это может сделать это быстрее , так как [[Prototype]]
цепочка не должна соблюдаться, но я подозреваю, что это незначительно, а не причина, по которой реализация является причиной.
... или мне не хватает каких-либо случаев, когда они
hasOwnProperty
могут использоваться для объектов, у которых нет этого метода?
hasOwnProperty()
существует Object.prototype
, но может быть отменено. Каждый собственный объект JavaScript (но объекты хоста не обязательно следуют этому, см. Подробное объяснение RobG ) имеет в Object.prototype
качестве своего последнего объекта в цепочке до null
(за исключением, конечно, объекта, возвращаемого Object.create(null)
).
const hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
Это может показаться разделением волос, но есть разница между 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.
Что неверно для определенных объектов хоста в IE в режиме совместимости (и IE 8 и ниже всегда), по крайней мере.
Учитывая вышеизложенное, стоит задуматься, почему у объекта может быть свой собственный метод hasOwnProperty, и целесообразно вместо него вызвать какой-либо другой метод hasOwnProperty без предварительного тестирования, является ли это хорошей идеей или нет.
редактировать
Я подозреваю, что причина использования
Object.prototype.hasOwnProperty.call
заключается в том, что в некоторых браузерах объекты хоста не имеют метода hasOwnProperty , альтернативой является использование call и встроенного метода. Однако делать это в целом не кажется хорошей идеей по причинам, указанным выше.Что касается хост-объектов, оператор in может использоваться для проверки свойств в целом, например
Альтернатива (проверено в IE6 и других):
Таким образом, вы специально вызываете встроенный hasOwnProperty только там, где объект не имеет его (унаследованный или иным образом).
Однако, если у объекта нет
hasOwnProperty
метода, вероятно, так же удобно использовать оператор in, поскольку объект, скорее всего, не имеет схемы наследования, и все свойства находятся в объекте (хотя это всего лишь предположение), например Оператор in - это распространенный (и, казалось бы, успешный) способ тестирования поддержки свойств объекта DOM.источник
in
не выполняетhasOwnProperty()
поиск, я подозреваю, что свойство, которое вы искали, существовало в цепочке прототипов.hasOwnProperty
непосредственно полученный объект, потому что злонамеренный клиент может отправить значение JSON, например,{"hasOwnProperty": 1}
и вызвать сбой сервера.Если существует вероятность того, что объект может иметь свойство с таким именем, необходимо использовать внешний hasOwnProperty для получения правильных результатов:
Вы можете скопировать и вставить приведенные ниже фрагменты кода в консоль своего браузера, чтобы лучше понять
Всегда возвращает false
Используйте hasOwnProperty другого объекта и вызовите его с этим значением foo
Также для этой цели можно использовать свойство hasOwnProperty из прототипа объекта.
источник
hasOwnProperty
возвратовtrue
.Информация, представленная в обоих существующих ответах, верна. Однако использование:
упоминается несколько раз. Следует отметить, что
hasOwnProperty
реализации вернут истину только в том случае, если свойство непосредственно содержится в тестируемом объекте.in
Оператор проверит вниз по цепочке прототипов тоже.Это означает, что свойства экземпляра вернут true при передаче,
hasOwnProperty
а свойства прототипа вернут false.При использовании
in
оператора свойства экземпляра и прототипа вернут true.источник