Skip to main content

Перевірка наявності властивості в об'єкті

У JavaScript є кілька способів перевірити, чи є в об'єкті та чи інша властивість, і кожен працює трохи по-різному. Різниця між ними в тому, чи враховується ланцюжок прототипів і чи можна обманути перевірку значенням undefined.

Теорія

TL;DR

  • 'key' in obj перевіряє наявність властивості, включно з успадкованими від прототипу.
  • obj.hasOwnProperty('key') бачить тільки власні властивості, але метод можна перевизначити.
  • Object.hasOwn(obj, 'key') (ES2022) це сучасна і безпечна заміна hasOwnProperty().
  • obj.key !== undefined перевіряє значення, а не наявність, тому помиляється на властивостях зі значенням undefined.
  • Reflect.has(obj, 'key') працює точно як in, зручний у метапрограмному коді.

Швидкий приклад

javascript
const user = { name: 'Alice', age: 25 }; console.log('name' in user); // true console.log(Object.hasOwn(user, 'name')); // true console.log('email' in user); // false

Оператор in

Найпряміший і найнадійніший спосіб перевірити, що властивість взагалі існує.

javascript
const user = { name: 'Alice', age: 25 }; console.log('name' in user); // true console.log('email' in user); // false

Оператор враховує весь ланцюжок прототипів:

javascript
const person = { isHuman: true }; const user = Object.create(person); user.name = 'Alice'; console.log('name' in user); // true, власна властивість console.log('isHuman' in user); // true, успадкована

Метод hasOwnProperty()

Перевіряє тільки власні властивості, тобто ті, що реально належать самому об'єкту, а не прототипу.

javascript
const person = { isHuman: true }; const user = Object.create(person); user.name = 'Alice'; console.log(user.hasOwnProperty('name')); // true console.log(user.hasOwnProperty('isHuman')); // false

Використовуйте його, коли треба переконатися, що властивість визначена в самому об'єкті, а не успадкована.

Обережно: якщо хтось перевизначив hasOwnProperty або об'єкт створено через Object.create(null) і прототипу в нього немає, метод краще викликати так:

javascript
Object.prototype.hasOwnProperty.call(user, 'name');

Метод Object.hasOwn()

Сучасна версія hasOwnProperty зі стандарту ES2022, безпечніша, бо не залежить від ланцюжка прототипів самого об'єкта.

javascript
const user = { name: 'Alice' }; console.log(Object.hasOwn(user, 'name')); // true console.log(Object.hasOwn(user, 'email')); // false

У новому коді рекомендують брати саме Object.hasOwn() замість hasOwnProperty().

Перевірка через undefined

Простий, але не завжди безпечний спосіб:

javascript
const user = { name: 'Alice' }; console.log(user.name !== undefined); // true console.log(user.email !== undefined); // false

Проблема в тому, що властивість може існувати, але мати значення undefined:

javascript
const user = { name: undefined }; console.log('name' in user); // true, властивість є console.log(user.name !== undefined); // false, перевірка обманює

Reflect.has() і порівняння способів

Ще один варіант, з Reflect API:

javascript
const user = { name: 'Alice' }; console.log(Reflect.has(user, 'name')); // true console.log(Reflect.has(user, 'email')); // false

Працює точно як in, але зручний у рефлексивному, метапрограмному коді, наприклад усередині пастки has у Proxy.

МетодБачить успадкованіТільки власніБезпечний для будь-яких об'єктівПриклад
'key' in objтакнітак'name' in user
obj.hasOwnProperty('key')нітакне завжди, метод можна перевизначитиuser.hasOwnProperty('name')
Object.hasOwn(obj, 'key')нітактакObject.hasOwn(user, 'name')
obj.key !== undefinedне завждинітакuser.name !== undefined
МетаНайкращий спосіб
------
Перевірити будь-яку властивість, включно з прототипними'prop' in obj
Перевірити тільки власну властивістьObject.hasOwn(obj, 'prop')
Підтримка старих браузерівobj.hasOwnProperty('prop')
Перевірити, що значення не undefinedobj.key !== undefined, обережно

Типові помилки

  • Перевіряти наявність через !== undefined. Властивість зі значенням undefined існує, але така перевірка дасть false.
  • Використовувати if (obj.count) як перевірку наявності. Значення 0, '', false і null теж falsy, тому наявне поле виглядатиме як відсутнє.
  • Викликати hasOwnProperty напряму на об'єкті з Object.create(null). Прототипу немає, тому метод недоступний і буде TypeError; беріть Object.hasOwn().
  • Плутати in з перебором. Для масивів in перевіряє індекс, а не значення: 1 in [10, 20] це true, а 20 in [10, 20] це false.
  • Забувати про успадковані поля. 'toString' in {} це true, бо метод приходить з Object.prototype.
  • Думати, що ?. замінює перевірку. user?.email тільки захищає від помилки на null, але не відрізняє відсутнє поле від поля зі значенням undefined.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.