Пошук уроків, статей та іншого контенту
Навчіться перевіряти наявність властивості в об'єкті за допомогою оператора in. Дізнайтеся, як успадковані властивості впливають на результат перевірки.
inОператор in перевіряє, чи існує властивість із певним ключем в об’єкті або в його ланцюжку прототипів.
Синтаксис:
propertyKey in objectРезультатом буде булеве значення:
true, якщо властивість знайдено;
false, якщо властивість не знайдено.
const user = {
name: "Olena",
age: 28
};
console.log("name" in user); // true
console.log("email" in user); // falseЛіворуч від in вказують ключ властивості, а праворуч — об’єкт, у якому потрібно виконати пошук.
Ключ можна записати як рядок або як вираз, результатом якого є ключ:
const product = {
title: "Keyboard",
price: 2500
};
const key = "price";
console.log(key in product); // true
console.log("title" in product); // true
console.log("stock" in product); // falseДля властивостей, записаних без лапок у літералі об’єкта, все одно використовуються рядкові ключі:
const settings = {
darkMode: true
};
console.log("darkMode" in settings); // true
console.log(darkMode in settings); // ReferenceErrorУ другому прикладі JavaScript намагається знайти змінну darkMode, а не використати рядок "darkMode".
Правильно:
console.log("darkMode" in settings); // trueЧислові ключі об’єктів фактично зберігаються як рядки:
const scores = {
1: 10,
2: 20
};
console.log(1 in scores); // true
console.log("1" in scores); // trueОператор in також підтримує ключі типу Symbol:
const id = Symbol("id");
const user = {
name: "Andrii",
[id]: 42
};
console.log(id in user); // true
console.log("id" in user); // falseОператор in перевіряє не лише власні властивості об’єкта. Він також шукає властивість у прототипі об’єкта та далі в ланцюжку прототипів.
const user = {
name: "Olena"
};
console.log("name" in user); // true
console.log("toString" in user); // trueВластивість toString не записана безпосередньо в об’єкті user. Вона успадковується від Object.prototype.
Це важлива відмінність:
in перевіряє власні й успадковані властивості;
Object.hasOwn() перевіряє лише власні властивості.
const user = {
name: "Olena"
};
console.log("name" in user); // true
console.log("name" in Object(user)); // true
console.log("toString" in user); // true
console.log(Object.hasOwn(user, "toString")); // falseconst animal = {
canEat: true
};
const dog = Object.create(animal);
dog.name = "Rex";
console.log("name" in dog); // true
console.log("canEat" in dog); // true
console.log("canRun" in dog); // false
console.log(Object.hasOwn(dog, "name")); // true
console.log(Object.hasOwn(dog, "canEat")); // falseОб’єкт dog має власну властивість name. Властивість canEat належить об’єкту animal, який є прототипом dog.
Саме тому:
"canEat" in dogповертає true, а:
Object.hasOwn(dog, "canEat")повертає false.
Оператор in перевіряє наявність ключа, а не значення за цим ключем.
Це особливо помітно, якщо властивість має значення undefined:
const config = {
timeout: undefined
};
console.log("timeout" in config); // true
console.log(config.timeout !== undefined); // falseВластивість timeout існує, але її значення дорівнює undefined.
Тому для перевірки саме наявності властивості використовуйте in або Object.hasOwn() залежно від потреби.
const data = {
value: undefined
};
if ("value" in data) {
console.log("Властивість існує");
}in і масивиМасиви є об’єктами, тому оператор in можна використовувати для перевірки індексів.
const colors = ["red", "green", "blue"];
console.log(0 in colors); // true
console.log(2 in colors); // true
console.log(3 in colors); // false
console.log("length" in colors); // trueВластивість length існує в масиві, тому результатом є true.
Оператор in розрізняє елемент, якого немає, і елемент зі значенням undefined.
const values = [];
values[1] = undefined;
console.log(values.length); // 2
console.log(0 in values); // false
console.log(1 in values); // true
console.log(values[1]); // undefinedУ позиції 0 немає властивості, а в позиції 1 властивість існує, хоча її значення — undefined.
Звичайна перевірка через індекс не дає такої інформації:
console.log(values[0] === undefined); // true
console.log(values[1] === undefined); // trueОбидва значення однакові, але причина різна. Для перевірки наявності індексу корисним є саме in.
in і Object.hasOwn()const prototype = {
inherited: true
};
const object = Object.create(prototype);
object.own = true;
console.log("own" in object); // true
console.log("inherited" in object); // true
console.log(Object.hasOwn(object, "own")); // true
console.log(Object.hasOwn(object, "inherited")); // falseВикористовуйте:
in, якщо потрібно враховувати успадковані властивості;
Object.hasOwn(), якщо потрібні лише властивості самого об’єкта.
in і перевірка на undefinedconst options = {
retries: undefined
};
console.log("retries" in options); // true
console.log(options.retries !== undefined); // falseПеревірка через !== undefined відповідає на інше питання: чи має властивість значення, відмінне від undefined.
in і метод hasOwnPropertyРаніше для перевірки власної властивості часто використовували:
object.hasOwnProperty("key")Однак це не завжди безпечно. Об’єкт може мати власну властивість із назвою hasOwnProperty або взагалі не мати прототипу:
const object = Object.create(null);
object.value = 10;
// object.hasOwnProperty("value"); // TypeError
console.log(Object.hasOwn(object, "value")); // trueДля сучасного JavaScript краще використовувати:
Object.hasOwn(object, "value");inПраворуч від in має бути об’єкт. Якщо передати null або undefined, виникне помилка TypeError.
const value = null;
// "name" in value; // TypeErrorПеред перевіркою можна переконатися, що значення є об’єктом:
const value = null;
if (value !== null && typeof value === "object") {
console.log("name" in value);
}Пам’ятайте, що функції також є об’єктами, тому оператор in можна застосовувати до них:
function greet() {}
console.log("name" in greet); // true
console.log("call" in greet); // trueУявімо функцію, яка визначає, як обробити повідомлення. Поле type може бути відсутнім, тому його потрібно перевірити перед використанням:
function processMessage(message) {
if (!message || typeof message !== "object") {
throw new TypeError("Повідомлення має бути об'єктом");
}
if ("error" in message) {
console.log("Повідомлення містить інформацію про помилку:");
console.log(message.error);
return;
}
if ("text" in message) {
console.log("Текстове повідомлення:");
console.log(message.text);
return;
}
console.log("Невідомий формат повідомлення");
}
processMessage({ text: "Привіт!" });
processMessage({ error: "Не вдалося завантажити дані" });
processMessage({ text: undefined });Для третього повідомлення перевірка "text" in message поверне true, оскільки властивість існує, навіть якщо її значення дорівнює undefined.
Якщо потрібно приймати лише власні поля повідомлення й ігнорувати властивості прототипу, використовуйте Object.hasOwn():
function hasOwnText(message) {
return (
message !== null &&
typeof message === "object" &&
Object.hasOwn(message, "text")
);
}
console.log(hasOwnText({ text: "Привіт" })); // true
console.log(hasOwnText({})); // falseinОператор in доречний у таких ситуаціях:
потрібно перевірити існування властивості незалежно від її значення;
успадковані властивості також мають враховуватися;
потрібно перевірити наявність індексу в масиві;
потрібно відрізнити відсутню властивість від властивості зі значенням undefined;
потрібно перевірити властивість із динамічним або символьним ключем.
Приклад із динамічним ключем:
function hasField(object, fieldName) {
return fieldName in object;
}
const formData = {
username: "developer",
email: "dev@example.com"
};
console.log(hasField(formData, "email")); // true
console.log(hasField(formData, "password")); // falseconst user = {
role: "admin"
};
console.log("admin" in user); // false
console.log("role" in user); // truein шукає ключ "role", а не значення "admin".
const user = {
name: "Olena"
};
console.log("toString" in user); // trueЯкщо потрібно перевірити тільки власні поля:
console.log(Object.hasOwn(user, "toString")); // false!== undefinedconst settings = {
debug: undefined
};
console.log(settings.debug !== undefined); // false
console.log("debug" in settings); // trueЦі перевірки мають різний сенс. Перша перевіряє значення, друга — наявність властивості.
in для примітивів// "length" in "hello"; // TypeErrorПраворуч має бути об’єкт:
console.log("length" in new String("hello")); // trueНа практиці для рядка зазвичай достатньо перевірити його властивість length без оператора in.
Оператор in перевіряє наявність властивості в об’єкті.
Результат перевірки — true або false.
in враховує як власні, так і успадковані властивості.
Властивість зі значенням undefined усе одно вважається наявною.
Для перевірки індексів масиву in дає змогу виявити пропущені елементи.
Object.hasOwn(object, key) перевіряє тільки власні властивості.
Праворуч від in має бути об’єкт, інакше виникне TypeError.
in перевіряє ключ, а не значення властивості.