Перейти к содержимому
Тема 13 из 16
Теория

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

Зачем это нужно

С объектами и массивами постоянно приходится делать одно и то же: достать несколько полей в переменные, скопировать, объединить два объекта, добавить элемент, не испортив оригинал. Современный JavaScript делает это короткими записями — деструктуризацией и оператором .... Их используют везде, особенно в React и при работе с данными от сервера.

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

«Разобрать» массив на переменные по порядку:

const point = [10, 20];
const [x, y] = point;
console.log(x, y);

const [first, , third] = ["а", "б", "в"];  // пропуск элемента — пустое место
console.log(first, third);

Вывод:

10 20
а в

Обмен значений без временной переменной:

let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a, b);

Вывод:

2 1

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

Из объекта переменные достаются по именам свойств:

const user = { name: "Аня", age: 15, city: "Худжанд" };
const { name, age } = user;
console.log(name, age);

const { city: town, country = "Таджикистан" } = user; // новое имя и значение по умолчанию
console.log(town, country);

Вывод:

Аня 15
Худжанд Таджикистан

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

function hello({ name, age }) {
  return `${name}, ${age} лет`;
}
console.log(hello({ name: "Тимур", age: 17, city: "Душанбе" }));

Вывод:

Тимур, 17 лет

Остаток ...rest

Три точки слева от = или в параметрах собирают «всё остальное»:

const [winner, ...others] = ["Аня", "Тимур", "Ира"];
console.log(winner, others);

const { password, ...safeUser } = { login: "anya", password: "123", age: 15 };
console.log(safeUser);

function sum(...nums) {        // любое количество аргументов
  return nums.reduce((s, n) => s + n, 0);
}
console.log(sum(1, 2, 3, 4));

Вывод:

Аня ["Тимур","Ира"]
{"login":"anya","age":15}
10

Spread ...

Те же три точки справа или в вызове «раскладывают» массив или объект:

const a = [1, 2];
const b = [3, 4];
console.log([...a, ...b, 5]);          // объединение
console.log(Math.max(...[4, 9, 2]));   // массив как отдельные аргументы

const base = { theme: "dark", lang: "ru" };
const mine = { ...base, lang: "tg" };  // копия с изменением
console.log(mine);
console.log(base);

Вывод:

[1,2,3,4,5]
9
{"theme":"dark","lang":"tg"}
{"theme":"dark","lang":"ru"}

При объединении объектов побеждает последнее значение: { ...base, lang: "tg" } перезаписывает lang.

Копия поверхностная!

const original = { name: "Аня", tags: ["js"] };
const copy = { ...original };
copy.name = "Ира";        // не влияет на оригинал
copy.tags.push("css");    // а это влияет!
console.log(original);

Вывод:

{"name":"Аня","tags":["js","css"]}

Spread копирует только верхний уровень. Вложенный массив tags остался общим — копия хранит ту же ссылку. Чтобы изменить вложенное без порчи оригинала, копируют и его: { ...original, tags: [...original.tags, "css"] }. Полную глубокую копию делает structuredClone(obj).

Сравнение объектов

console.log({ a: 1 } === { a: 1 });
const x = { a: 1 };
const y = x;
console.log(x === y);

Вывод:

false
true

=== для объектов и массивов сравнивает ссылки, а не содержимое: равны только если это один и тот же объект.

Как это работает внутри

Деструктуризация — просто короткая запись. const { name, age } = user — это то же самое, что const name = user.name; const age = user.age;. А { ...a, ...b } создаёт новый пустой объект и по очереди копирует в него свойства a, затем b. Значения-объекты при этом не копируются — копируется ссылка на них. Отсюда и «поверхностность».

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

  1. Перепутали скобки. Массив разбирают квадратными [a, b] = arr, объект — фигурными { a } = obj.
  2. Имя не совпадает со свойством. const { username } = { name: "Аня" } → undefined. Нужно { name: username }.
  3. ...rest не последним. const [...rest, last] = arr — ошибка: остаток всегда последний.
  4. Думать, что spread копирует глубоко. Вложенные массивы и объекты остаются общими.
  5. Порядок при объединении. { lang: "tg", ...base } — lang из base перезапишет твой.

Шпаргалка

Что Как
Разобрать массив const [a, b] = arr;
Разобрать объект const { name, age } = obj;
Переименовать / по умолчанию const { city: town, x = 0 } = obj;
В параметрах function f({ name }) { … }
Остаток const [first, ...rest] = arr;
Любое число аргументов function f(...args) { … }
Копия / объединение массивов [...a], [...a, ...b]
Копия / объединение объектов { ...o }, { ...o, key: 1 }
Глубокая копия structuredClone(o)

Обмен

Лёгкая+10 XP

Напиши функцию swapPair(pair). Она получает массив из двух элементов и возвращает новый массив, где они поменялись местами. Используй деструктуризацию массива в параметре.

swapPair([1, 2])        → [2, 1]
swapPair(["x", "y"])    → ["y", "x"]

Подключи коннектор, чтобы решать задачи

Код задач выполняется на твоём компьютере — так быстрее и надёжнее, чем в браузере. Для этого нужна бесплатная программа-коннектор CodeWithMe. Подключить её нужно один раз.

Ищем коннектор на этом компьютере…

  1. 1
    Скачай коннектор для своей системы (Windows, macOS или Linux).Скачать коннекторНа странице загрузки выбери файл со своей системой в названии, например windows-amd64.
  2. 2Запусти его и выбери папку, где будут лежать твои решения. Python и Node.js он поставит туда сам, когда понадобится.
  3. 3
    Введи ниже код из 6 цифр — он написан в окне коннектора («Код для сайта CodeWithMe»). Если браузер спросит про доступ к локальной сети — разреши.

Коннектор открытый (исходный код на GitHub), работает только на твоём компьютере и выполняет код лишь после ввода кода сопряжения.