Перейти к содержимому
Теория · Объекты · урок 9 из 13

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

Часто из анкеты нужны две-три строки, и дальше с ними работают по отдельности. Их переписывают на листки: на листок name — имя, на листок age — возраст. В коде это по строке на свойство: const city = user.city.

Ту же работу можно сделать одной строкой:

JavaScript
const user = { name: "Ann", age: 30, city: "Oslo" };

const city = user.city;
const { name, age } = user;

console.log(name, age, city); // Ann 30 Oslo

Давайте разберём пример по строкам:

  1. const city = user.city — привычная запись: одна переменная, одно свойство.
  2. const { name, age } = user создаёт сразу две переменные, name и age, и кладёт в них свойства user с теми же именами.
  3. console.log печатает Ann 30 Oslo.

Запись const { name, age } = user называется деструктуризацией. Переменные в фигурных скобках слева получают свойства объекта справа с теми же именами. Имена должны совпадать с ключами: const { nme } = user даёт undefined, потому что свойства nme нет. Сам объект при этом не меняется.

На листок попадает копия значения, а анкета остаётся прежней. Здесь аналогия перестаёт работать для вложенных объектов: если в свойстве лежит объект, переменная получает ссылку на него, как поверхностная копия.

Значения по умолчанию

Если свойства нет, переменная получает undefined. Значение после = внутри фигурных скобок, как в const { y = 0 } = point, подставляется вместо undefined. Так же работают параметры по умолчанию у функций.

Свойство со значением null или 0 остаётся как есть: значение по умолчанию заменяет только undefined.

Другое имя

Двоеточие даёт переменной другое имя: { x: left } кладёт свойство x в переменную left. Слева от двоеточия стоит имя свойства, справа — имя новой переменной, а переменной x при этом не появляется.

Другое имя нужно, когда имя свойства уже занято или ничего не говорит о данных. Например, в программе уже есть переменная x, и вторую с тем же именем объявить нельзя.

Обе записи сочетаются в одних скобках. После const { x: left, y = 0 } = { x: 3 } в left лежит 3, а в y — 0.

В параметрах функции

Деструктуризация работает и в списке параметров. Функция получает один объект и сразу раскладывает его по переменным:

JavaScript
function area({ width, height = 1 }) {
    return width * height;
}

console.log(area({ width: 2, height: 3 })); // 6
console.log(area({ width: 5 })); // 5

Разберём по строкам:

  1. area разбирает свой единственный параметр-объект прямо в списке параметров.
  2. Вызов area({ width: 2, height: 3 }) кладёт 2 в width, 3 в height и возвращает 6.
  3. Во втором вызове свойства height нет, и оно получает значение по умолчанию 1: результат 5.

Порядок свойств в аргументе не важен: они находятся по именам. Поэтому функцию с параметром-объектом трудно вызвать неправильно, перепутав аргументы местами.

Массивы

Квадратные скобки слева разбирают массив по позициям. Первая переменная получает элемент с индексом 0, вторая — с индексом 1. У элементов массива нет подписей, как у строк анкеты, поэтому имена переменных любые: важна позиция.

Та же запись помогает ещё в двух случаях:

  • поменять местами значения двух переменных;
  • разобрать пары из Object.entries.
JavaScript
const [first, second] = [10, 20, 30];
console.log(first, second); // 10 20

let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1

for (const [key, value] of Object.entries({ x: 1, y: 2 })) {
    console.log(key, value);
}
// x 1
// y 2

Третий элемент 30 в первой строке никуда не попадает. Если переменных больше, чем элементов, лишние получают undefined.

Справа в [a, b] = [b, a] создаётся новый массив из старых значений. Слева он разбирается обратно в a и b. Обмен значений без третьей переменной часто просят показать на собеседовании.

В цикле по Object.entries пара сразу раскладывается на key и value, без entry[0] и entry[1].

Частая ошибка

Функцию, которая разбирает объект-параметр, вызвали без аргумента:

JavaScript
function greet({ name }) {
    return `Hi, ${name}`;
}

console.log(greet()); // ✗
TEXT
TypeError: Cannot destructure property 'name' of 'undefined' as it is undefined.

Без аргумента параметр равен undefined, а у undefined свойств не бывает.

Дайте параметру значение по умолчанию: с function greet({ name = "guest" } = {}) вызов greet() возвращает Hi, guest. Пустой объект {} подставляется вместо отсутствующего аргумента, а name получает значение по умолчанию.

Главное

  • const { name, age } = user кладёт свойства в переменные с теми же именами; отсутствующее свойство даёт undefined.
  • { y = 0 } задаёт значение по умолчанию, а { x: left } кладёт свойство x в переменную left.
  • const [first, second] = arr разбирает массив по позициям, а [a, b] = [b, a] меняет значения местами.
  • Параметр-объект без аргумента ломает разбор, поэтому ему дают значение по умолчанию = {}.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом