Learn JavaScript

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

Деструктуризация - это синтаксис, который позволяет “распаковать” значения из объекта или массива в отдельные переменные. Чаще всего она нужна, чтобы код был короче и читался проще.

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

Базовый пример

const user = { name: "Sam", age: 20 };

const { name, age } = user;

console.log(name); // "Sam"
console.log(age);  // 20

Имена переменных совпадают с ключами объекта.

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

Когда нужно другое имя переменной:

const user = { name: "Sam", age: 20 };

const { name: userName, age: userAge } = user;

console.log(userName); // "Sam"
console.log(userAge);  // 20

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

Если свойства нет, можно задать значение по умолчанию.

const user = { name: "Sam" };

const { name, city = "Unknown" } = user;

console.log(name); // "Sam"
console.log(city); // "Unknown"

Деструктуризация вложенных объектов

const user = {
  profile: {
    name: "Sam",
    contacts: {
      email: "sam@example.com"
    }
  }
};

const {
  profile: {
    name,
    contacts: { email }
  }
} = user;

console.log(name);  // "Sam"
console.log(email); // "sam@example.com"

Здесь создаются переменные name и email. Переменная profile не создается, потому что это часть шаблона.

Остаток (rest) в объекте

...rest собирает оставшиеся свойства в новый объект.

const user = { id: 1, name: "Sam", age: 20 };

const { id, ...rest } = user;

console.log(id);   // 1
console.log(rest); // { name: "Sam", age: 20 }

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

Базовый пример

В массиве значения идут по позиции.

const nums = [10, 20, 30];

const [a, b, c] = nums;

console.log(a); // 10
console.log(b); // 20
console.log(c); // 30

Пропуск элементов

const nums = [10, 20, 30, 40];

const [first, , third] = nums;

console.log(first); // 10
console.log(third); // 30

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

const nums = [10];

const [a, b = 0] = nums;

console.log(a); // 10
console.log(b); // 0

Остаток (rest) в массиве

...rest собирает оставшиеся элементы в новый массив.

const nums = [10, 20, 30, 40];

const [first, ...rest] = nums;

console.log(first); // 10
console.log(rest);  // [20, 30, 40]

Частые сценарии

1) Пары из Object.entries

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

const user = { name: "Sam", age: 20 };

for (const [key, value] of Object.entries(user)) {
  console.log(key, value);
}

2) Параметры функции как объект

Частый прием - принимать объект и сразу деструктурировать нужные поля.

function formatUser({ name, age }) {
  return name + " (" + age + ")";
}

console.log(formatUser({ name: "Sam", age: 20 })); // "Sam (20)"

Если некоторые поля могут отсутствовать, задаются значения по умолчанию:

function formatUser({ name = "Unknown", age = 0 } = {}) {
  return name + " (" + age + ")";
}

console.log(formatUser({ name: "Sam" })); // "Sam (0)"
console.log(formatUser()); // "Unknown (0)"

Здесь = {} защищает от случая, когда аргумент не передан.

Частые ошибки

1) Путаница: свойства нет, но default не сработал

Значение по умолчанию срабатывает только если свойство равно undefined. Если в объекте null, default не применяется.

const user = { city: null };

const { city = "Unknown" } = user;

console.log(city); // null

Если нужен дефолт и для null, используют ??:

const user = { city: null };

const { city } = user;
const safeCity = city ?? "Unknown";

console.log(safeCity); // "Unknown"

2) Ошибка при деструктуризации из null/undefined

try {
  const { a } = undefined;
  console.log(a);
} catch (e) {
  console.log(e.name); // "TypeError"
}

Если объект может быть отсутствующим, помогает значение по умолчанию:

const source = undefined;

const { a = 0 } = source ?? {};
console.log(a); // 0

Что стоит запомнить

  • Деструктуризация распаковывает значения из объекта или массива в переменные.
  • Для объекта важны имена ключей, для массива - порядок элементов.
  • Можно задавать значения по умолчанию и переименовывать переменные.
  • ...rest собирает остаток в новый объект или массив.
  • В параметрах функций деструктуризация делает код чище, но важно добавлять защиту через = {} при необходимости.