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

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

Зачем нужно

Деструктуризация сокращает код и делает его выразительнее. Вместо user.name, user.age можно сразу получить name и age.

Где используется

  • Извлечение данных из API-ответов
  • Параметры функций
  • Импорт модулей
  • Обмен переменных
  • React (useState, props)

Предпосылки

Объекты, Массивы

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

const user = { name: 'Алиса', age: 25, city: 'Москва' };

// Базовая
const { name, age, city } = user;
console.log(name); // 'Алиса'
console.log(age);  // 25

// Переименование
const { name: userName, age: userAge } = user;
console.log(userName); // 'Алиса'

// Значения по умолчанию
const { name, country = 'Россия' } = user;
console.log(country); // 'Россия' (свойства нет в user)

// Переименование + значение по умолчанию
const { name: n, role: userRole = 'user' } = user;
console.log(userRole); // 'user'

// Rest (остальные свойства)
const { name, ...rest } = user;
console.log(rest); // { age: 25, city: 'Москва' }

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

const colors = ['red', 'green', 'blue', 'yellow'];

// Базовая
const [first, second, third] = colors;
console.log(first);  // 'red'
console.log(second); // 'green'

// Пропуск элементов
const [, , thirdColor] = colors;
console.log(thirdColor); // 'blue'

// Значения по умолчанию
const [a, b, c, d, e = 'black'] = colors;
console.log(e); // 'black'

// Rest (остаток массива)
const [head, ...tail] = colors;
console.log(head); // 'red'
console.log(tail); // ['green', 'blue', 'yellow']

// Обмен переменных
let x = 1, y = 2;
[x, y] = [y, x];
console.log(x, y); // 2, 1

Вложенная деструктуризация

// Вложенные объекты
const response = {
  data: {
    user: {
      name: 'Алиса',
      contacts: {
        email: 'alice@mail.com',
        phone: '+7999'
      }
    }
  },
  status: 200
};

const {
  data: {
    user: {
      name,
      contacts: { email }
    }
  },
  status
} = response;

console.log(name);   // 'Алиса'
console.log(email);  // 'alice@mail.com'
console.log(status); // 200

// Вложенные массивы
const matrix = [[1, 2], [3, 4], [5, 6]];
const [[a, b], [c, d]] = matrix;
console.log(a, b, c, d); // 1 2 3 4

// Смешанная (объект + массив)
const config = {
  servers: ['primary.com', 'backup.com'],
  settings: { timeout: 3000 }
};

const {
  servers: [primary, backup],
  settings: { timeout }
} = config;
console.log(primary); // 'primary.com'
console.log(timeout); // 3000

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

// Объект как параметр
function createUser({ name, age, role = 'user' }) {
  return { name, age, role, createdAt: new Date };
}

createUser({ name: 'Алиса', age: 25 });
// { name: 'Алиса', age: 25, role: 'user', createdAt: ... }

// Массив как параметр
function getFirst([first, ...rest]) {
  return { first, rest };
}

getFirst([1, 2, 3]); // { first: 1, rest: [2, 3] }

// Значение по умолчанию для всего параметра
function setup({ port = 3000, host = 'localhost' } = {}) {
  console.log(`${host}:${port}`);
}

setup;                    // 'localhost:3000'
setup({ port: 8080 });     // 'localhost:8080'

// Деструктуризация в forEach/map
const users = [
  { name: 'Алиса', age: 25 },
  { name: 'Боб', age: 30 }
];

users.forEach(({ name, age }) => {
  console.log(`${name}: ${age}`);
});

const names = users.map(({ name }) => name);
// ['Алиса', 'Боб']

Деструктуризация с вычисляемыми ключами

const key = 'name';
const user = { name: 'Алиса', age: 25 };

const { [key]: value } = user;
console.log(value); // 'Алиса'

// Динамическое извлечение
function extract(obj, ...keys()) {
  return keys.map(key => {
    const { [key]: value } = obj;
    return value;
  });
}
extract(user, 'name', 'age'); // ['Алиса', 25]

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

1. Деструктуризация null/undefined

// const { name } = null; // TypeError!

// Решение: значение по умолчанию
const { name } = someValue ?? {};

2. Объявление без let/const

let name, age;
// { name, age } = user; // SyntaxError — JS считает { за начало блока

// Решение: обернуть в скобки
({ name, age } = user); // OK

3. Слишком глубокая вложенность

// Плохо: трудно читать
const { data: { users: [{ contacts: { email: { primary } } }] } } = response;

// Лучше: в несколько шагов
const { data } = response;
const [firstUser] = data.users;
const { primary } = firstUser.contacts.email;

Практика

  1. Деструктурируй ответ API: { data: { items: [...], total }, status }
  2. Напиши функцию с деструктурированными параметрами и значениями по умолчанию
  3. Обменяй три переменные без временной переменной
  4. Извлеки первый и последний элементы массива одним выражением

Связанные темы

Ресурсы


⚡ Источник: JavaScript Destructuring Assignment или не все то золото · AsForJS

  • 📅 2023-05-15 · YouTube
  • Тезисы:
    • Деструктуризация — это не магия, а синтаксический сахар над [[Get]]. const {a, b} = obj = const a = obj.a; const b = obj.b
    • Деструктуризация массива использует итератор (Symbol.iterator), не индексы! const [a, b] = obj сработает если у obj есть Symbol.iterator
    • С values по умолчанию: {a = 5} = {a: undefined}a = 5, но {a: null}a = null (default срабатывает ТОЛЬКО на undefined)

⚡ Источник: Что Вы не знаете о Assignment Patterns · AsForJS

  • 📅 2025-10-18 · YouTube
  • Тезисы: В спеке Assignment Pattern (({a} = obj)) и Binding Pattern (let {a} = obj) — разные грамматические продукции. Скобки вокруг ({a} = obj) обязательны при assignment без let/const

⚡ Источник: Выражаем себя через Rest и Spread · AsForJS

  • 📅 2025-10-31 · YouTube
  • Тезисы: Rest pattern в деструктуризации ({a, ...rest}) делает Object Rest copy — это shallow copy всех enumerable own properties кроме перечисленных. Symbol-ключи копируются