Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Перевірка наявності властивості в об'єкті». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Основних способів чотири: оператор `in` (бачить і власні, і успадковані властивості), `Object.hasOwn()` (сучасна і безпечна перевірка тільки власних), `obj.hasOwnProperty()` (те саме, але його можна перевизначити) і порівняння `obj.key !== undefined` (найшвидше, але бреше, коли значення справді `undefined`).** У сучасному коді беруть `in`, коли важливий увесь ланцюжок прототипів, і `Object.hasOwn()`, коли потрібні лише власні поля. ```javascript const user = { name: 'Alice', email: undefined }; console.log('email' in user); // true console.log(Object.hasOwn(user, 'email')); // true console.log(user.email !== undefined); // false, обманює ``` **Ключове:** `in` перевіряє наявність властивості, а `!== undefined` перевіряє її значення, і це різні питання.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**У 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')` | | Перевірити, що значення не `undefined` | `obj.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`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.