$ sudo teach IT
РАЗДЕЛ 7 · УРОК 6

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

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

⏱ ~25 минут 🎓 Для новичков 📦 JavaScript

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

Раньше, чтобы достать элементы из массива в переменные, приходилось писать так:

const colors = ["красный", "зелёный", "синий"];

// Старый способ — многословно
const first = colors[0];
const second = colors[1];
const third = colors[2];

С деструктуризацией это одна строка. Смотрите на синтаксис: квадратные скобки слева от знака равно — это деструктуризация массива:

const colors = ["красный", "зелёный", "синий"];

// Деструктуризация массива
const [first, second, third] = colors;

console.log(first);  // → "красный"
console.log(second); // → "зелёный"
console.log(third);  // → "синий"

Работает по позиции: первая переменная получает первый элемент, вторая — второй, и так далее.

💡 Чтение деструктуризации: const [a, b] = arr — читается «создай переменные a и b, присвоив им первый и второй элементы arr». Квадратные скобки слева — не массив, это паттерн деструктуризации!

✂️ Пропуск элементов, rest и значения по умолчанию

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

Если какой-то элемент не нужен — просто оставьте пустое место (запятую без имени переменной):

const [a, , c] = [10, 20, 30];
// Пропустили 20
console.log(a); // → 10
console.log(c); // → 30

// Пропустить первый, взять второй и третий
const [, second, third] = ["игнорируем", "берём", "и это"];
console.log(second); // → "берём"

Rest-элемент: собрать остаток

Оператор ... перед именем переменной соберёт «всё оставшееся» в массив:

const numbers = [1, 2, 3, 4, 5];

const [first, second, ...rest] = numbers;
console.log(first);  // → 1
console.log(second); // → 2
console.log(rest);   // → [3, 4, 5]

// Полезно для разделения «головы» и «хвоста» списка
const [head, ...tail] = ["яблоко", "банан", "вишня", "груша"];
console.log(head); // → "яблоко"
console.log(tail); // → ["банан", "вишня", "груша"]

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

Если элемента нет (или он undefined), можно задать значение по умолчанию через =:

const [x = 0, y = 0, z = 0] = [10, 20];
console.log(x); // → 10 (из массива)
console.log(y); // → 20 (из массива)
console.log(z); // → 0 (по умолчанию, элемента нет)

// Полезно при работе с API, где данных может не быть
const [status = "unknown", code = 200] = getResponse();

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

Для объектов деструктуризация работает по именам свойств (не по позиции). Используются фигурные скобки:

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

// Старый способ
const name1 = user.name;
const age1 = user.age;

// Деструктуризация объекта — коротко и ясно!
const { name, age } = user;
console.log(name); // → "Алиса"
console.log(age);  // → 25

// Можно взять несколько свойств сразу
const { name: n, age: a, city } = user;
// name → "Алиса", age → 25, city → "Москва"

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

Переименование при деструктуризации

Если имя свойства вас не устраивает (или уже занято) — переименуйте через ::

const user = { name: "Боб", age: 30 };

// Берём name, но называем переменную userName
const { name: userName, age: userAge } = user;

console.log(userName); // → "Боб"
console.log(userAge);  // → 30
// console.log(name);  // ошибка: name не объявлена!

Значения по умолчанию для объектов

const settings = { theme: "dark" };

const { theme = "light", lang = "ru", fontSize = 16 } = settings;

console.log(theme);    // → "dark" (из объекта)
console.log(lang);     // → "ru" (по умолчанию)
console.log(fontSize); // → 16 (по умолчанию)

Rest для объектов

const person = { name: "Карл", age: 22, city: "Казань", role: "user" };

// Взять name и age, остальное — в отдельный объект
const { name, age, ...rest } = person;

console.log(name); // → "Карл"
console.log(age);  // → 22
console.log(rest); // → { city: "Казань", role: "user" }

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

Это один из самых мощных и практичных применений деструктуризации. Особенно часто встречается в React-компонентах:

// Без деструктуризации — громоздко
function greetUser(user) {
  console.log(`Привет, ${user.name}! Тебе ${user.age} лет.`);
}

// С деструктуризацией в параметрах — чисто и красиво
function greetUser({ name, age }) {
  console.log(`Привет, ${name}! Тебе ${age} лет.`);
}

const alice = { name: "Алиса", age: 25, city: "Москва" };
greetUser(alice); // → "Привет, Алиса! Тебе 25 лет."

// Со значениями по умолчанию прямо в параметрах
function createProfile({ name, role = "user", active = true }) {
  return { name, role, active };
}

createProfile({ name: "Боб" });
// → { name: "Боб", role: "user", active: true }

createProfile({ name: "Диана", role: "admin" });
// → { name: "Диана", role: "admin", active: true }

🌟 В React это стандарт! Все компоненты получают объект props. С деструктуризацией: function Button({ label, onClick, disabled = false }). Без неё пришлось бы писать props.label, props.onClick везде.

🔀 Swap переменных и вложенная деструктуризация

🔄 Обмен значениями (swap) за одну строку

Классическая задача «поменять значения двух переменных» раньше требовала временной переменной. Деструктуризация решает это элегантно:

// Старый способ — нужна временная переменная
let a = 1, b = 2;
let temp = a;
a = b;
b = temp;

// С деструктуризацией — одна строка!
let x = 10, y = 20;
[x, y] = [y, x];
console.log(x); // → 20
console.log(y); // → 10

// Реальный пример: сортировка пузырьком
if (arr[i] > arr[i + 1]) {
  [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]];
}

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

Можно деструктурировать вложенные структуры. Главное — не переусердствовать, иначе код станет нечитаемым:

const data = {
  user: {
    name: "Алиса",
    address: {
      city: "Москва"
    }
  }
};

// Вложенная деструктуризация объекта
const { user: { name, address: { city } } } = data;
console.log(name); // → "Алиса"
console.log(city); // → "Москва"

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

⚠️ Не злоупотребляйте вложенной деструктуризацией. Два уровня — нормально. Три и больше — код становится трудночитаемым. Лучше разбейте на несколько строк.

💡 Практические паттерны

// 1. Деструктуризация возвращаемого значения функции
function getMinMax(arr) {
  return {
    min: Math.min(...arr),
    max: Math.max(...arr)
  };
}

const { min, max } = getMinMax([3, 1, 4, 1, 5, 9]);
console.log(min, max); // → 1 9

// 2. Деструктуризация в forEach/map
const users = [
  { name: "Алиса", score: 92 },
  { name: "Боб", score: 78 }
];

users.forEach(({ name, score }) => {
  console.log(`${name}: ${score} баллов`);
});
// → "Алиса: 92 баллов"
// → "Боб: 78 баллов"

// 3. Деструктуризация в map — очень распространённый паттерн
const names = users.map(({ name }) => name);
console.log(names); // → ["Алиса", "Боб"]

// 4. Деструктуризация ответа от API
const { data, status, error = null } = await fetchUser(id);
if (status === 200) {
  const { name, email } = data;
  // работаем с данными
}

✅ Итоги урока

  • Деструктуризация массивов: const [a, b] = arr — извлекает по позиции
  • Пропуск: const [a, , c] = arr — пропустить второй элемент
  • Rest в массиве: const [first, ...rest] = arr — остаток в массиве
  • Деструктуризация объектов: const { name, age } = obj — извлекает по имени
  • Переименование: const { name: myName } = obj — свойство name → переменная myName
  • Значения по умолчанию: const { x = 0 } = obj — если свойства нет, x = 0
  • Rest в объекте: const { a, ...rest } = obj — остаток в новом объекте
  • Swap переменных: [a, b] = [b, a] — обмен значениями за одну строку
  • Деструктуризация в параметрах функции — стандарт для React-компонентов

Поздравляем! Раздел 7 завершён. Вы освоили функциональные инструменты JavaScript, которые используются в 90% реального кода: колбэки, map/filter/reduce, sort и деструктуризацию. Это серьёзный уровень! 🎉

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

7 вопросов

Обмен значений через деструктуризацию

Напишите функцию swap, которая принимает массив из двух элементов [a, b] и возвращает новый массив [b, a], используя деструктуризацию (без временной переменной).

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

Напишите функцию printUser, которая принимает объект { name, age, city } и возвращает строку 'Имя: name, Возраст: age, Город: city'. Используйте деструктуризацию прямо в параметрах функции.