Чем отличаются in и hasOwnProperty()?

👨‍💻 Frontend Developer 🟠 Может встретиться 🎚️ Средний
#JavaScript #Объекты #База JS

Краткий ответ

Оператор in проверяет, существует ли свойство в объекте или его цепочке прототипов. Метод hasOwnProperty() проверяет только собственные свойства объекта, игнoring унаследованные. Главное отличие: in видит всё, hasOwnProperty только своё.


Полный ответ

В JavaScript есть два способа проверить наличие свойства в объекте: оператор [in] и метод hasOwnProperty(). Они похожи, но имеют важное отличие.

Как работает оператор in

Проверяет свойство в объекте и его прототипах:

const obj = { name: 'Иван' };
console.log('name' in obj); // true
console.log('toString' in obj); // true (унаследованное)

Как работает hasOwnProperty()

Проверяет только собственные свойства объекта:

const obj = { name: 'Иван' };
console.log(obj.hasOwnProperty('name')); // true
console.log(obj.hasOwnProperty('toString')); // false

Главные отличия

Оператор in

  • Видит собственные свойства
  • Видит унаследованные свойства
  • Проверяет всю цепочку прототипов

hasOwnProperty()

  • Видит только собственные свойства
  • Игнорирует унаследованные свойства
  • Проверяет только сам объект

Простые примеры

Когда важно различие

const user = { name: 'Иван' };
 
// Проверка с in
if ('toString' in user) {
  console.log('toString есть'); // Сработает
}
 
// Проверка с hasOwnProperty
if (user.hasOwnProperty('toString')) {
  console.log('toString есть'); // Не сработает
}

Когда что использовать

Используй оператор in когда:

  • Нужно проверить любое свойство, включая унаследованные
  • Работаешь с полиморфизмом
  • Хочешь знать, можно ли обращаться к свойству

Используй hasOwnProperty() когда:

  • Нужно проверить только свои свойства
  • Хочешь отличить свои свойства от унаследованных
  • Работаешь с объектом как с картой данных

Важные особенности

1. Унаследованные методы

const obj = {};
// Все объекты имеют унаследованные методы
console.log('toString' in obj); // true
console.log(obj.hasOwnProperty('toString')); // false

2. Прототипная цепочка

const parent = { inherited: 'value' };
const child = Object.create(parent);
child.own = 'value';
 
console.log('inherited' in child); // true (через прототип)
console.log(child.hasOwnProperty('inherited')); // false (не своё)

Частые ошибки

1. Непонимание наследования

// ❌ Думаем, что toString свойство объекта
const obj = {};
if (obj.hasOwnProperty('toString')) {
  console.log('Есть toString');
} else {
  console.log('Нет toString'); // Сработает правильно
}
 
// ✅ Правильная проверка для общего случая
if ('toString' in obj) {
  console.log('Можно использовать toString'); // Сработает
}

2. Использование только hasOwnProperty

// ❌ Пропускаем унаследованные методы
const obj = { name: 'Иван' };
for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    // Пропустили toString и другие методы
  }
}
 
// ✅ Если нужны все свойства
for (let key in obj) {
  if (key in obj) {
    // Будет работать, но бессмысленно
    // Лучше без проверки
  }
}

Простые правила

  1. in — для общей проверки наличия свойства
  2. hasOwnProperty — для проверки только собственных свойств
  3. Унаследованные — in видит, hasOwnProperty не видит
  4. Цепочка прототипов — in проходит по ней, hasOwnProperty нет
  5. Практика — чаще нужен hasOwnProperty для работы с данными

Понимание разницы между in и hasOwnProperty помогает правильно работать с объектами и избегать ошибок с наследованными свойствами.


Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪