Деструктуризация объектов в JavaScript

Деструктуризация объекта позволяет достать свойства объекта и сразу записать их в переменные.

let user = {
  name: 'Анна',
  age: 28,
};

let { name, age } = user;

console.log(name); // Анна
console.log(age); // 28

Такой код читается короче, чем несколько отдельных обращений через точку.

Что такое деструктуризация

Деструктуризация - это специальный синтаксис для извлечения данных из объекта.

let { name } = user;

Эта запись означает: возьми из объекта user свойство name и создай переменную с таким же именем.

Имя переменной по умолчанию совпадает с именем свойства.

Обычный доступ и деструктуризация

Без деструктуризации мы обычно обращаемся к свойствам через точку.

let user = {
  name: 'Анна',
  age: 28,
};

let name = user.name;
let age = user.age;

console.log(name); // Анна
console.log(age); // 28

С деструктуризацией то же самое можно записать короче.

let user = {
  name: 'Анна',
  age: 28,
};

let { name, age } = user;

console.log(name); // Анна
console.log(age); // 28

В обоих случаях мы получаем обычные переменные name и age.

Несколько свойств

Через деструктуризацию можно достать только те свойства, которые нужны.

let product = {
  title: 'Клавиатура',
  price: 2500,
  inStock: true,
};

let { title, price } = product;

console.log(title); // Клавиатура
console.log(price); // 2500

Свойство inStock осталось в объекте. Деструктуризация не удаляет свойства, а только создает переменные.

Если свойства нет

Если свойства в объекте нет, переменная получит значение undefined.

let user = {
  name: 'Анна',
};

let { email } = user;

console.log(email); // undefined

Это похоже на обычное обращение к отсутствующему свойству.

console.log(user.email); // undefined

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

Для отсутствующего свойства можно указать значение по умолчанию.

let user = {
  name: 'Анна',
};

let { name, role = 'user' } = user;

console.log(name); // Анна
console.log(role); // user

Если свойство role есть в объекте, будет взято его значение. Если свойства нет, используется значение после знака =.

let user = {
  name: 'Анна',
  role: 'admin',
};

let { role = 'user' } = user;

console.log(role); // admin

Переименование переменных

Иногда имя свойства не подходит для имени переменной. Тогда переменную можно назвать иначе.

let user = {
  name: 'Анна',
};

let { name: userName } = user;

console.log(userName); // Анна

Запись name: userName означает: возьми свойство name, но сохрани его в переменную userName.

Переменная name в таком случае не создается.

Вложенные объекты

Деструктуризацию можно использовать и для вложенных объектов.

let user = {
  name: 'Анна',
  contacts: {
    email: 'anna@example.com',
  },
};

let {
  contacts: { email },
} = user;

console.log(email); // anna@example.com

Здесь мы достали свойство email из объекта contacts.

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

let email = user.contacts?.email;

Деструктуризация в параметрах функции

Деструктуризация часто встречается в параметрах функции, когда функция принимает объект.

function printUser(user) {
  console.log(user.name);
  console.log(user.age);
}

Если функции нужны только отдельные свойства, их можно достать сразу в параметрах.

function printUser({ name, age }) {
  console.log(name);
  console.log(age);
}

let user = {
  name: 'Анна',
  age: 28,
};

printUser(user);

Такой вариант удобен, когда по названию параметров сразу понятно, какие данные нужны функции.

Оставшиеся свойства

Иногда нужно достать часть свойств, а остальные собрать в отдельный объект.

let user = {
  name: 'Анна',
  age: 28,
  city: 'Москва',
};

let { name, ...details } = user;

console.log(name); // Анна
console.log(details); // { age: 28, city: 'Москва' }

…details собирает оставшиеся свойства объекта. Это похоже на rest parameters у функций, но применяется к свойствам объекта.

Итого

  • Деструктуризация достает свойства объекта в переменные.
  • let { name } = user создает переменную name со значением user.name.
  • Если свойства нет, переменная получит undefined.
  • Значение по умолчанию записывают через =.
  • Через двоеточие можно сохранить свойство в переменную с другим именем.
  • В параметрах функции деструктуризация помогает сразу получить нужные свойства объекта.
  • …rest собирает оставшиеся свойства в новый объект.