Объекты
Зачем это нужно
Массив хранит список по порядку. А как описать одну вещь со многими характеристиками — например, пользователя с именем, возрастом и городом? Для этого есть объект: набор пар «ключ — значение». Почти всё в JavaScript — объекты: данные с сервера, настройки, товары, сообщения. Это самая важная структура данных языка.
Создание и чтение
const user = {
name: "Аня",
age: 15,
city: "Худжанд",
};
console.log(user.name); // Аня — через точку
console.log(user["city"]); // Худжанд — через квадратные скобки
console.log(user.email); // undefined — такого свойства нет
Пары ключ: значение перечисляются через запятую в фигурных скобках. Ключи ещё называют
свойствами (properties).
Точка или скобки? Обычно точка. Квадратные скобки нужны, когда имя ключа лежит в переменной или содержит пробел или дефис:
const field = "age";
console.log(user[field]); // 15
const car = { "max-speed": 220 };
console.log(car["max-speed"]); // 220
Изменить, добавить, удалить
const user = { name: "Аня", age: 15 };
user.age = 16; // изменить
user.city = "Душанбе"; // добавить новое
delete user.name; // удалить
console.log(user);
Вывод:
{"age":16,"city":"Душанбе"}
Как и с массивами, const не мешает менять содержимое объекта — запрещено только положить в переменную другой объект.
Проверить, есть ли свойство
const settings = { theme: "dark", volume: 0 };
console.log("theme" in settings); // true
console.log("lang" in settings); // false
console.log(settings.volume ?? 50); // 0 — ?? не путает 0 с отсутствием
Короткая запись
Если имя переменной совпадает с именем ключа, можно писать один раз:
const name = "Тимур";
const age = 17;
const user = { name, age }; // то же, что { name: name, age: age }
console.log(user);
Вывод:
{"name":"Тимур","age":17}
Перебор объекта
const prices = { tea: 50, coffee: 90, juice: 70 };
for (const key in prices) {
console.log(key, prices[key]);
}
console.log(Object.keys(prices)); // ключи
console.log(Object.values(prices)); // значения
console.log(Object.entries(prices)); // пары [ключ, значение]
Вывод:
tea 50
coffee 90
juice 70
["tea","coffee","juice"]
[50,90,70]
[["tea",50],["coffee",90],["juice",70]]
Object.keys/values/entries возвращают массивы, поэтому к ним подходят все методы массивов:
Object.values(prices).reduce((s, p) => s + p, 0) → 210.
Вложенность и массивы объектов
Значением свойства может быть что угодно — массив, другой объект:
const student = {
name: "Ира",
marks: [5, 4, 5],
address: { city: "Бохтар", street: "Рудаки" },
};
console.log(student.address.city);
console.log(student.marks[1]);
Вывод:
Бохтар
4
Очень частая структура — массив объектов: список товаров, пользователей, сообщений.
Методы и this
Если значение свойства — функция, его называют методом:
const counter = {
value: 0,
increase() {
this.value++;
},
};
counter.increase();
counter.increase();
console.log(counter.value);
Вывод:
2
this внутри метода — это объект, у которого метод вызвали (здесь counter). Для методов используй
такую короткую запись или function, но не стрелку: у стрелочных функций нет своего this.
Как это работает внутри
Объект — как шкаф с подписанными ящиками: по подписи (ключу) ящик находится сразу, без перебора всех.
Поэтому obj[key] работает очень быстро даже для огромных объектов — именно поэтому объекты
удобны для подсчёта и группировки. Ключи объекта всегда строки (числа превращаются в строки):
obj[1] и obj["1"] — одно и то же свойство.
Переменная хранит не объект, а ссылку на него — как и с массивами. const b = a не копирует объект:
a и b указывают на один и тот же. Копирование — в следующей теме.
Частые ошибки
- Точка с переменной.
obj.key, когда имя ключа в переменнойkey, ищет свойство с именем"key". Нужноobj[key]. - Забыли запятую между свойствами.
{ a: 1 b: 2 }— синтаксическая ошибка. =вместо:внутри объекта.{ name = "Аня" }— ошибка. Внутри объекта — двоеточие.- Прибавление к несуществующему.
counts[word]++для нового слова дастNaN(undefined + 1). Сначала нужен0:(counts[word] ?? 0) + 1. - Стрелка как метод с
this.{ go: () => this.x }—thisбудет не объектом.
Шпаргалка
| Что | Как |
|---|---|
| Создать | const o = { a: 1, b: "x" }; |
| Читать | o.a, o["a"], o[key] |
| Изменить / добавить | o.a = 2; o.c = true; |
| Удалить | delete o.a |
| Есть ли | "a" in o |
| Короткая запись | { name, age } |
| Перебор | for (const k in o), Object.keys/values/entries(o) |
| Метод | { go() { this.x++; } } |