Зачем использовать объект.прототип.метод hasOwnProperty.вызовите (myObj, prop) вместо myObj.метод hasOwnProperty(проп)?

если я правильно понимаю, каждый объект в Javascript наследуется от прототипа объекта, что означает, что каждый объект в Javascript имеет доступ к функции hasOwnProperty через свою цепочку прототипов.

во время чтения требуют.исходный код js, я наткнулся на эту функцию:

function hasProp(obj, prop) {
    return hasOwn.call(obj, prop);
}

hasOwn ссылочка Object.prototype.hasOwnProperty. Есть ли практическая разница в написании этой функции как

function hasProp(obj, prop) {
    return obj.hasOwnProperty(prop);
}

и так как мы на это, почему мы вообще определяем эту функцию? Это просто вопрос ярлыков и локального кэширования доступа к свойствам для (небольшого) повышения производительности, или мне не хватает случаев, когда hasOwnProperty может использоваться для объектов, у которых нет этого метода?

4 ответов


есть ли какая-либо практическая разница [между моими примерами]?

пользователь может иметь объект JavaScript, созданный с помощью Object.create(null), которые будут null [[Prototype]] цепь, и поэтому не будет иметь hasOwnProperty() имеющиеся на нем. Использование второй формы не сработает по этой причине.

это также более безопасная ссылка на Object.prototype.hasOwnProperty() (и короче).

вы можете себе представить, кто такое мог сделать...

var someObject = {
    hasOwnProperty: function(lol) {
        return true;
    }
};

что бы hasProp(someObject) fail если бы он был реализован как ваш второй пример (он нашел бы этот метод непосредственно на объекте и вызвал бы это, вместо того, чтобы делегироваться Object.prototype.hasOwnProperty).

но менее вероятно, что кто-то переопределит Object.prototype.hasOwnProperty ссылка.

и поскольку мы на нем, почему мы вообще определяем эту функцию?

см. выше.

это просто вопрос ярлыков и локального кэширования недвижимости доступ к (небольшое) увеличение производительности...

это может сделать его быстрее в теории, как [[Prototype]] цепь не должна следовать, но я подозреваю, что это незначительно и не причина реализации почему.

... или я пропускаю какие-либо случаи, когда hasOwnProperty может использоваться на объектах, которые не имеют этот метод?

hasOwnProperty() существует Object.prototype, но может быть переопределенный. Каждый собственный объект JavaScript (но объекты хоста не гарантируется следовать этому,посмотреть RobG углубленного объяснения) и Object.prototype как его последний объект в цепочке перед null (за исключением, конечно, объекта, возвращаемого Object.create(null)).


если я правильно понимаю, каждый объект в Javascript наследуется от прототипа объекта

Это может показаться казуистикой, но есть разница между в JavaScript (общий термин для реализаций ECMAScript) и ECMAScript (язык, используемый для реализаций JavaScript). Именно ECMAScript определяет схему наследования, а не javascript, поэтому реализовать нужно только собственные объекты ECMAScript эта схема наследования.

запущенная программа javascript состоит, по крайней мере, из встроенных объектов ECMAScript (объект, функция, номер и т.д.) и, вероятно, некоторые собственные объекты (например, функции). Он также может иметь некоторые объекты (например, объекты DOM в браузере, или другие объекты в других хост-средах).

в то время как встроенные и собственные объекты должны реализовать схему наследования, определенную в ECMA–262, объекты хоста этого не делают. Поэтому не все объекты в javascript среды должны наследовать от


JavaScript не защищает имя свойства hasOwnProperty

если существует возможность, что объект может иметь свойство с этим именем, необходимо использовать внешний hasOwnProperty для получения правильных результатов:

вы можете скопировать вставить приведенные ниже фрагменты кода в консоль браузеров, чтобы получить лучшее понимание

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'I belong to foo'
};

всегда возвращает false

foo.hasOwnProperty('bar'); // false

использовать другой Объект hasOwnProperty и вызовите его с помощью этой установить в foo

({}).hasOwnProperty.call(foo, 'bar'); // true

также можно использовать свойство hasOwnProperty из объект прототипом для этой цели

Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

информация, приведенная в обоих существующих ответах, находится на месте. Однако использование:

('propertyName' in obj)

упоминается несколько раз. Следует отметить, что hasOwnProperty реализации вернут true только в том случае, если свойство непосредственно содержится в тестируемом объекте.

на in оператор проверит вниз через цепь прототипа тоже.

это означает, что свойства экземпляра вернут true при передаче в hasOwnProperty где как прототип свойства, будет возвращено значение false.

С помощью in оператор свойства экземпляра и прототипа вернут true.