Skip to main content

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

Наявність властивості в об'єкті перевіряють оператором in, методом hasOwnProperty(), функцією Object.hasOwn() або порівнянням значення з undefined. Ці способи не взаємозамінні: вони по-різному поводяться з прототипом і по-різному реагують на властивість, значення якої дорівнює undefined.

Теорія

TL;DR

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

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

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

Оператор in, найуніверсальніший спосіб

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

Оператор перевіряє, чи є ключ в об'єкті, разом з властивостями, успадкованими від прототипу. Ліворуч від in стоїть рядок або Symbol, праворуч, сам об'єкт.

Приклад зі спадкуванням:

javascript
const person = { species: 'human' }; const user = Object.create(person); user.name = 'Maria'; console.log('species' in user); // true (успадковано)

Тут species немає безпосередньо в user, але воно є в його прототипі person, тому in повертає true. Саме тому 'toString' in {} теж дає true: метод приходить з Object.prototype.

Метод hasOwnProperty(), тільки власні властивості

javascript
const user = { name: 'Maria', age: 25 }; console.log(user.hasOwnProperty('age')); // true console.log(user.hasOwnProperty('city')); // false

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

Приклад різниці:

javascript
const person = { species: 'human' }; const user = Object.create(person); user.name = 'Maria'; console.log('species' in user); // true console.log(user.hasOwnProperty('species')); // false

Object.hasOwn(), сучасний аналог hasOwnProperty

ES2022 додав безпечніший і читабельніший спосіб:

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

Працює так само, як hasOwnProperty, але не залежить від того, що відбувається всередині самого об'єкта. Два випадки, де hasOwnProperty ламається, а Object.hasOwn ні:

javascript
// 1. Об'єкт без прототипу: методу hasOwnProperty просто немає. const dict = Object.create(null); dict.token = 1; // dict.hasOwnProperty('token'); // TypeError console.log(Object.hasOwn(dict, 'token')); // true // 2. Власна властивість з таким самим іменем перекриває метод. const data = { hasOwnProperty: () => false, id: 7 }; console.log(data.hasOwnProperty('id')); // false, перевизначено console.log(Object.hasOwn(data, 'id')); // true

Перевірка на undefined, найпростіша, але не завжди точна

javascript
const user = { name: 'Maria' }; if (user.age !== undefined) { console.log('Властивість age є'); } else { console.log('Властивості age немає'); }

Мінус: якщо властивість є, але її значення дорівнює undefined, ви отримаєте хибне спрацювання.

javascript
const user = { age: undefined }; console.log(user.age !== undefined); // false, хоча ключ існує

Так само помилковою є скорочена перевірка if (user.age): вона відкине 0, '', null і false, які є цілком валідними значеннями.

Порівняння способів

СпосібЩо перевіряєВраховує прототипНадійність
'key' in objнаявність ключаТакВідмінний вибір
obj.hasOwnProperty('key')тільки власні властивостіНіКласика
Object.hasOwn(obj, 'key')тільки власні властивостіНіСучасний стандарт
obj.key !== undefinedзначення не undefinedНіМоже бути хибним

Щоб перевірити, чи є властивість в об'єкті, використовуйте 'key' in obj, коли важливі всі властивості разом з успадкованими, або Object.hasOwn(obj, 'key'), коли потрібні тільки власні.

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

  • Плутати наявність ключа і його значення. obj.key !== undefined поверне false для властивості, яка існує зі значенням undefined. Перевіряйте ключ через in або Object.hasOwn.
  • Скорочувати до if (obj.key). Значення 0, '', null, NaN і false є хибними (falsy), тому існуючі властивості будуть «загублені».
  • Забувати про прототип. Оператор in бачить toString, constructor та інші успадковані властивості, тому для перевірки даних, що прийшли ззовні, беріть Object.hasOwn.
  • Викликати hasOwnProperty на об'єкті з Object.create(null). Такий об'єкт не має прототипу, тому методу в нього немає і виклик кине TypeError.
  • Довіряти hasOwnProperty, коли дані прийшли від користувача. Вхідний JSON може містити власний ключ hasOwnProperty і перекрити метод. Object.hasOwn або Object.prototype.hasOwnProperty.call(obj, key) від цього захищені.
  • Писати in з ім'ям змінної без лапок. key in obj перевіряє значення змінної key, а 'key' in obj, буквальний ключ "key". Це різні перевірки.

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

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

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