Что делает метод hasOwnProperty в JavaScript
Что проверяют
Понимание прототипов, а не знание одного метода. Вопрос простой на входе, но интервьюер обычно тянет его дальше: чем отличается от оператора in, что вернётся для значения undefined, как проверить свойство у объекта без прототипа. По этим уточнениям и видно глубину.
Как отвечать
Метод живёт в Object.prototype и возвращает true, если свойство собственное, то есть лежит в самом объекте, а не унаследовано по цепочке прототипов. Он видит и неперечисляемые свойства, и символьные ключи, и возвращает true для свойства, значение которого равно undefined. Оператор in ведёт себя иначе: он говорит true и про унаследованное.
const obj = Object.create({ inherited: 1 });
obj.own = 2;
obj.hasOwnProperty("own"); // true
obj.hasOwnProperty("inherited"); // false
"inherited" in obj; // trueСовременный способ вызвать то же самое безопасно это статический Object.hasOwn(obj, key). Он не сломается, если объект создан через Object.create(null) или если в данных есть собственный ключ с именем метода. До его появления писали громоздкое Object.prototype.hasOwnProperty.call(obj, key).
Где спотыкаются
Зовут метод прямо на объекте с произвольными ключами. Объект без прототипа его не имеет, а пришедшее извне поле с таким именем затеняет метод и делает вызов ошибкой. Линтер ругается на это правилом no-prototype-builtins именно поэтому, а не из вредности.
Используют проверку как проверку значения. Свойство со значением undefined даёт true, а привычное сравнение obj.key !== undefined в том же случае даёт false. Обратная крайность это проверка через if (obj.key), которая отбрасывает ноль, пустую строку и false.
Ждут, что метод сработает на чём угодно. У экземпляра класса методы лежат в прототипе, поэтому по ним вернётся false. Для Map нужен map.has(key), потому что ключи там вообще не являются свойствами объекта.