JavaScriptJuniorCoding

Что такое деструктуризация (destructuring assignment)? Приведите примеры с массивами и объектами.

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

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

Деструктуризация — синтаксический сахар над присваиванием: JS «сопоставляет» шаблон слева с данными справа и разбирает их по переменным. Поддерживаются массивы, объекты, вложенные структуры и параметры функций.

Массивы

const rgb = [255, 128, 0];

// Базовое извлечение
const [r, g, b] = rgb;          // 255, 128, 0

// Пропуск элементов
const [, , blue] = rgb;         // blue = 0

// Дефолт (только когда значение === undefined)
const [x, y, z = 1, w = 2] = [10, 20]; // z=1, w=2

// Swap без temp-переменной
let a = 1, b2 = 2;
[a, b2] = [b2, a];              // a=2, b2=1

// Rest
const [head, ...tail] = [1, 2, 3, 4]; // head=1, tail=[2,3,4]

Объекты

const user = {
  id: 42,
  name: 'Alice',
  address: { city: 'Berlin', zip: '10115' },
  role: undefined,
};

// Базовое
const { id, name } = user;

// Переименование
const { id: userId, name: userName } = user;

// Дефолт (только для undefined, не для null!)
const { role = 'viewer' } = user;  // role = 'viewer'
const { role: r = 'viewer' } = { role: null }; // r = null — дефолт НЕ применяется

// Вложенная деструктуризация
const { address: { city, zip } } = user;

// Rest
const { id: uid, ...rest } = user; // rest = { name, address, role }

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

// Вместо function render(options) { const title = options.title ... }
function render({ title = 'Untitled', maxWidth = 800 } = {}) {
  return `<section style="max-width:${maxWidth}px"><h1>${title}</h1></section>`;
}

render({ title: 'Hello' }); // maxWidth = 800
render();                    // дефолт = {} предотвращает TypeError

Практический пример: fetch-ответ

async function loadUser(id) {
  const res = await fetch(`/api/users/${id}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);

  const { data: { id: userId, name, email }, meta: { updatedAt } } = await res.json();
  return { userId, name, email, updatedAt };
}

Подводные камни

  • null не триггерит дефолт. Дефолтное значение подставляется только при undefined. Если API возвращает { role: null }, дефолт = 'viewer' не сработает — переменная получит null.
  • Вложенная деструктуризация выбрасывает TypeError при null/undefined. const { address: { city } } = user упадёт, если user.address равен null. Используйте опциональную цепочку или промежуточный дефолт: const { address: { city } = {} } = user.
  • Деструктуризация объекта в начале строки. { a, b } = obj без const/let/var парсится как блок, а не деструктуризация — нужны скобки: ({ a, b } = obj).
  • Rest должен быть последним. const { ...rest, id } = obj — синтаксическая ошибка; rest-элемент всегда идёт в конце паттерна.
  • Производительность при глубоком вложении. Многоуровневая деструктуризация в hot path (например, внутри Array.prototype.reduce на тысячах элементов) создаёт лишние временные объекты. Прямой доступ через точку быстрее.
  • Читаемость при переименовании + дефолт. const { x: myX = 0 } = obj — порядок читается как «взять x, переименовать в myX, дефолт 0». Многие путают порядок и пишут const { myX = 0: x } = obj, что является ошибкой.

Common mistakes

  • Смешивать «деструктуризация» с похожим механизмом без критерия выбора.
  • Игнорировать риск: неверно оценить границы применения темы «деструктуризация» и получить хрупкое решение.
  • Показывать только синтаксис и не объяснять поведение в runtime или сборке.

What the interviewer is testing

  • Объясняет извлечение значений из массивов и объектов с дефолтами и переименованием.
  • Показывает на примере, как работает: деструктуризация сопоставляет форму слева со значением справа, позволяет брать вложенные свойства и задавать default только когда значение undefined.
  • Называет production-нюанс и граничный случай для темы «деструктуризация».

Sources

Related topics