Деструктуризация в JavaScript: объекты и массивы
Содержание
О проверке кода. Примеры не запускались — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».
Деструктуризация — из ECMAScript 6, и это одна из тех вещей, после которых старый код читать больно. Разберём, как вынимать данные из объектов и массивов кратко.
Разбор объекта
const user = { name: 'Аня', age: 30, city: 'Москва' };
// без деструктуризации
const name = user.name;
const age = user.age;
// с деструктуризацией — одна строка
const { name, age } = user;
Имена переменных совпадают с именами свойств — JavaScript берёт user.name и кладёт в name. Порядок неважен, важны имена. Свойства, которые не упомянули, просто не берутся.
Разбор массива
const coords = [55.75, 37.61];
const [lat, lng] = coords; // lat = 55.75, lng = 37.61
// пропустить элемент — оставить пустое место
const [first, , third] = [1, 2, 3]; // first = 1, third = 3
// поменять переменные местами без временной
let a = 1, b = 2;
[a, b] = [b, a]; // a = 2, b = 1
Массив разбирают по позиции, не по имени. Первая переменная — первый элемент, и так далее. Пропущенную позицию оставляют пустой (запятая без имени). Обмен переменных местами [a, b] = [b, a] — классический трюк, который деструктуризация делает элегантным.
Именно так Geolocation API отдаёт координаты, а Object.entries — пары ключ-значение: for (const [key, value] of ...).
Значения по умолчанию
const { role = 'user' } = { name: 'Аня' }; // role = 'user' — свойства не было
const { name = 'гость' } = { name: 'Борис' }; // name = 'Борис' — свойство есть
const [x = 0, y = 0] = [5]; // x = 5, y = 0
Значение по умолчанию подставляется, если свойства нет или оно undefined. Это защищает от undefined при разборе неполных объектов — то же поведение, что у параметров функций по умолчанию.
Переименование
const { name: userName, age: userAge } = user;
// переменные будут userName и userAge, а не name и age
Через двоеточие свойство попадает в переменную с другим именем. Нужно, когда имя свойства конфликтует с уже существующей переменной или когда хочется более говорящее имя. Синтаксис путает новичков: слева от : — имя свойства в объекте, справа — имя новой переменной.
Комбинируется с дефолтами:
const { role: userRole = 'user' } = obj; // переименовать И задать умолчание
Вложенная деструктуризация
const user = {
name: 'Аня',
address: { city: 'Москва', zip: '101000' },
};
const { name, address: { city } } = user;
// name = 'Аня', city = 'Москва'
Можно разбирать вложенные структуры сразу. Но осторожно: address: { city } не создаёт переменную address — только city. Если нужны обе, укажите явно. Глубокая вложенность быстро становится нечитаемой — тогда лучше разобрать в два шага.
Главное применение: параметры функции
Здесь деструктуризация раскрывается полностью:
// ❌ много позиционных аргументов — легко перепутать порядок
function createUser(name, age, city, isAdmin, sendEmail) {}
createUser('Аня', 30, 'Москва', false, true); // что означает true?
// ✅ объект-настройки с деструктуризацией и дефолтами
function createUser({ name, age, city = 'не указан', isAdmin = false }) {
// ...
}
createUser({ name: 'Аня', age: 30, city: 'Москва' }); // понятно, что к чему
Позиционные аргументы
Порядок важен и легко перепутать
fn(a, b, c, d)- Что значит четвёртый
true? - Пропустить средний нельзя
- Добавить параметр — сломать порядок
Объект + деструктуризация
Именованные, с дефолтами
fn({ name, size = 10 })- Порядок неважен, всё по именам
- Легко пропустить необязательное
- Новый параметр не ломает вызовы
Как только у функции больше двух-трёх параметров — переходите на объект-настройки. Вызов становится самодокументируемым, порядок перестаёт иметь значение, а добавление нового параметра не ломает существующие вызовы. Этот приём используют React-компоненты (props), опции API и большинство современных библиотек.
Деструктуризация с rest
Собрать «всё остальное» в отдельную переменную:
const { name, ...rest } = { name: 'Аня', age: 30, city: 'Москва' };
// name = 'Аня', rest = { age: 30, city: 'Москва' }
const [head, ...tail] = [1, 2, 3, 4];
// head = 1, tail = [2, 3, 4]
...rest собирает то, что не разобрали явно. Частый приём — вынуть одно свойство, а остальное передать дальше: const { password, ...safe } = user убирает пароль перед отправкой объекта клиенту. Подробнее — про spread и rest.
Смежные темы: spread и rest — три точки подробно; объекты; функции — параметры. Полный список — в уроках JavaScript.