Перейти к содержанию
Educora
Средний17 мин9 / 27

Объекты, деструктуризация и spread

Храни все свойства одной сущности вместе в объекте, распаковывай их деструктуризацией, копируй и объединяй с помощью `...`.

Проверь себя
В этом уроке ты узнаешь
  • Создавать объект, читать, изменять, добавлять и удалять свойства
  • Выполнять деструктуризацию объектов и массивов
  • Копировать и объединять с помощью ... и понимать копирование по ссылке
  • Безопасно обрабатывать отсутствующие значения с ?. и ??

В ученическом билете указаны имя, возраст, город и увлечения. Их можно хранить в четырёх отдельных переменных, но они связаны — все описывают одного ученика. В JavaScript все данные об одной сущности хранят вместе — в объекте.

Объекты и свойства

Определение
Объект

Набор пар ключ: значение в фигурных скобках. Каждая пара называется свойством; значение может быть любого типа — число, строка, массив, другой объект или функция.

К свойству обращаются через точку (student.name) или через квадратные скобки (student['name']). Скобки нужны, когда имя ключа хранится в переменной. Чтобы добавить новое свойство, достаточно присвоить ему значение, а delete удаляет свойство.

JavaScript
const student = {
  name: 'Aysel',
  age: 14,
  city: 'Baku',
  hobbies: ['chess', 'music'],
};

console.log(student.name);
console.log(student['city']);
console.log(student.hobbies[1]);

const key = 'age';
console.log(student[key]);

student.age = 15;
student.grade = 9;
delete student.city;
console.log(student);
▸ Ожидаемый результат
Aysel
Baku
music
14
{ name: 'Aysel', age: 15, hobbies: [ 'chess', 'music' ], grade: 9 }

Свойство, значение которого — функция, называется методом. Внутри метода слово this указывает на сам объект. А Object.keys, Object.values и Object.entries возвращают ключи, значения и пары объекта в виде массивов — их удобно перебирать в цикле.

JavaScript
const counter = {
  count: 0,
  increase() {
    this.count++;
    return this.count;
  },
};
counter.increase();
console.log(counter.increase());

const prices = { bread: 0.8, milk: 1.5, tea: 4 };
console.log(Object.keys(prices));
console.log(Object.values(prices));
for (const item of Object.keys(prices)) {
  console.log(`${item}: ${prices[item]} AZN`);
}
▸ Ожидаемый результат
2
[ 'bread', 'milk', 'tea' ]
[ 0.8, 1.5, 4 ]
bread: 0.8 AZN
milk: 1.5 AZN
tea: 4 AZN

В реальных программах чаще всего работают с массивом объектов: товары магазина, ученики класса, заказы. Здесь очень пригодятся методы массивов из прошлого урока.

JavaScript
const products = [
  { name: 'Laptop', price: 1200 },
  { name: 'Mouse', price: 25 },
  { name: 'Desk', price: 300 },
];

const cheap = products
  .filter((p) => p.price < 500)
  .map((p) => p.name);
const total = products.reduce((sum, p) => sum + p.price, 0);

console.log(cheap);
console.log('Total:', total);
console.log(products.find((p) => p.price > 1000));
▸ Ожидаемый результат
[ 'Mouse', 'Desk' ]
Total: 1525
{ name: 'Laptop', price: 1200 }

Деструктуризация

Деструктуризация позволяет в одной строке извлечь несколько значений из объекта или массива в отдельные переменные. У объекта переменные выбираются по именам ключей, у массива — по позиции. Можно также переименовать (name: firstName) и задать значение по умолчанию (country = 'Azerbaijan').

JavaScript
const user = { name: 'Murad', age: 16, city: 'Ganja' };

const { name, age } = user;
console.log(name, age);

const { name: firstName, country = 'Azerbaijan' } = user;
console.log(firstName, country);

const [gold, silver] = ['Leyla', 'Elvin', 'Aysel'];
console.log(gold, silver);

function printCard({ name, city }) {
  console.log(`${name} lives in ${city}`);
}
printCard(user);
▸ Ожидаемый результат
Murad 16
Murad Azerbaijan
Leyla Elvin
Murad lives in Ganja

Spread и rest: три точки

Оператор ... «раскладывает» массив или объект — это называется spread. С его помощью можно делать копии, объединять массивы и создавать новый объект с изменёнными свойствами. Если одно и то же свойство встречается дважды, побеждает последнее. А в деструктуризации ... собирает «всё остальное» — это rest.

JavaScript
const morning = ['tea', 'bread'];
const evening = ['soup', 'salad'];
const menu = [...morning, 'lunch', ...evening];
console.log(menu);
console.log(Math.max(...[4, 17, 9]));

const defaults = { theme: 'light', lang: 'az', fontSize: 16 };
const settings = { ...defaults, theme: 'dark' };
console.log(settings);

const { lang, ...others } = settings;
console.log(lang, others);
▸ Ожидаемый результат
[ 'tea', 'bread', 'lunch', 'soup', 'salad' ]
17
{ theme: 'dark', lang: 'az', fontSize: 16 }
az { theme: 'dark', fontSize: 16 }
JavaScript
const original = { score: 10 };
const sameObject = original;
const copy = { ...original };

sameObject.score = 99;

console.log(original.score);
console.log(copy.score);
▸ Ожидаемый результат
99
10

Отсутствующие значения: ?. и ??

В данных с сервера некоторых свойств может не быть. Попытка прочитать свойство у null вызывает ошибку. Опциональная цепочка ?. это предотвращает: если слева null или undefined, она просто возвращает undefined. А оператор ?? даёт запасное значение справа, когда слева null или undefined.

JavaScript
const account = { login: 'elvin', profile: null };

console.log(account.profile?.avatar);
console.log(account.profile?.avatar ?? 'default.png');

const volume = 0;
console.log(volume || 50);
console.log(volume ?? 50);
▸ Ожидаемый результат
undefined
default.png
50
0
|| заменяет любое ложноподобное значение (включая 0), а ?? — только null и undefined.
Задание

1) С помощью деструктуризации возьми из student поля name и city и выведи их в одну строку. 2) Через spread создай копию объекта, где age равен 16, и выведи копию. 3) Выведи student.age, чтобы убедиться, что оригинал не изменился.

Задание · JavaScript
const student = { name: 'Murad', age: 15, city: 'Baku' };
// 1) destructure name and city and print them
// 2) copy the object with spread, set age to 16, print the copy
// 3) print student.age
▸ Ожидаемый результат
Murad Baku
{ name: 'Murad', age: 16, city: 'Baku' }
15

Главное

  • Объект состоит из пар ключ: значение; к свойствам обращаются через . или [ ].
  • Свойство-функция — это метод; внутри него this — сам объект.
  • Деструктуризация const { a, b } = obj и const [x, y] = arr извлекает значения в переменные.
  • ... как spread копирует и объединяет, а как rest — собирает остальное.
  • b = a — не копия объекта, а ссылка на тот же объект.
  • ?. защищает от ошибок при отсутствующих свойствах, ?? даёт запасное значение.

Проверь себя

Вопросов: 10. Каждый правильный ответ приносит XP.

1 / 10
Как прочитать свойство, если имя ключа хранится в переменной field?