Spread и rest оператор в JavaScript: разница, примеры и типичные ошибки
Если вы ищете spread оператор в JavaScript или пытаетесь понять разницу между spread и rest, главный факт такой: синтаксис один и тот же — ..., но смысл зависит от места использования. Spread «раскрывает» массив или объект, а rest «собирает» оставшиеся значения.
Коротко: spread vs rest
Оператор ... в JavaScript используется в двух ролях:
- Spread — разворачивает элементы массива, объекта или аргументы функции.
- Rest — собирает несколько значений в массив или объект.
Проще всего запомнить так: если ... стоит «на входе» и собирает остаток — это rest. Если «на выходе» раскрывает данные — это spread.
Spread оператор для массивов
Spread часто используют, чтобы скопировать массив, объединить несколько массивов или передать элементы массива как отдельные аргументы.
const numbers = [1, 2, 3];
const copy = [...numbers];
console.log(copy); // [1, 2, 3]
const moreNumbers = [0, ...numbers, 4];
console.log(moreNumbers); // [0, 1, 2, 3, 4]
Это удобнее и читаемее, чем старые варианты с concat или ручным циклом.
const frontend = ['HTML', 'CSS'];
const backend = ['Node.js', 'PostgreSQL'];
const stack = [...frontend, 'JavaScript', ...backend];
console.log(stack);
// ['HTML', 'CSS', 'JavaScript', 'Node.js', 'PostgreSQL']
Передача массива в функцию
Допустим, функция ожидает отдельные аргументы, а у вас есть массив. Spread решает это одной строкой.
const prices = [120, 450, 80, 900];
console.log(Math.max(...prices)); // 900
console.log(Math.min(...prices)); // 80
Без spread пришлось бы использовать менее очевидную запись:
console.log(Math.max.apply(null, prices));
Spread оператор для объектов
Spread можно применять и к объектам. Это популярный способ создать копию объекта или собрать новый объект на основе существующего.
const user = {
name: 'Анна',
age: 25
};
const userCopy = { ...user };
console.log(userCopy); // { name: 'Анна', age: 25 }
Также spread удобно использовать для обновления отдельных свойств:
const user = {
name: 'Анна',
age: 25,
city: 'Москва'
};
const updatedUser = {
...user,
age: 26
};
console.log(updatedUser);
// { name: 'Анна', age: 26, city: 'Москва' }
Важный момент: если свойства повторяются, побеждает значение, которое указано позже.
const result = {
role: 'user',
role: 'admin'
};
console.log(result.role); // 'admin'
Практический пример: настройки по умолчанию
Spread часто используют для объединения пользовательских настроек с настройками по умолчанию.
const defaultSettings = {
theme: 'light',
notifications: true,
language: 'ru'
};
const userSettings = {
theme: 'dark'
};
const finalSettings = {
...defaultSettings,
...userSettings
};
console.log(finalSettings);
// { theme: 'dark', notifications: true, language: 'ru' }
Такой подход часто встречается в реальных проектах: при настройке компонентов, запросов, форм, фильтров и конфигураций.
Rest параметры в функциях
Теперь посмотрим на rest. В параметрах функции ... собирает оставшиеся аргументы в массив.
function sum(...numbers) {
let total = 0;
for (const number of numbers) {
total += number;
}
return total;
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(10, 20, 30, 40)); // 100
Rest параметр должен быть последним в списке параметров:
function createUser(name, ...skills) {
return {
name,
skills
};
}
console.log(createUser('Игорь', 'JS', 'React', 'Git'));
// { name: 'Игорь', skills: ['JS', 'React', 'Git'] }
А вот так делать нельзя:
// Ошибка: rest параметр должен быть последним
function badExample(...items, lastItem) {
// ...
}
Rest при деструктуризации массивов
Rest можно использовать, чтобы взять первый элемент массива, а остальные собрать отдельно.
const fruits = ['apple', 'banana', 'orange', 'mango'];
const [firstFruit, ...otherFruits] = fruits;
console.log(firstFruit); // 'apple'
console.log(otherFruits); // ['banana', 'orange', 'mango']
Rest при деструктуризации объектов
С объектами принцип похожий: можно извлечь нужные свойства, а остальные собрать в новый объект.
const product = {
id: 101,
title: 'Клавиатура',
price: 3500,
inStock: true
};
const { id, ...productInfo } = product;
console.log(id); // 101
console.log(productInfo);
// { title: 'Клавиатура', price: 3500, inStock: true }
Это полезно, когда нужно исключить часть данных перед отправкой на сервер или отображением в интерфейсе.
Важная ошибка: spread делает поверхностную копию
Многие новички думают, что { ...object } полностью копирует объект. На самом деле создаётся только поверхностная копия. Вложенные объекты остаются связанными.
const user = {
name: 'Олег',
address: {
city: 'Казань'
}
};
const copy = { ...user };
copy.address.city = 'Самара';
console.log(user.address.city); // 'Самара'
Если нужно безопасно копировать вложенные структуры, используйте специальные способы глубокого копирования, например structuredClone, если он подходит для ваших данных.
const safeCopy = structuredClone(user);
safeCopy.address.city = 'Уфа';
console.log(user.address.city); // 'Самара'
console.log(safeCopy.address.city); // 'Уфа'
Когда использовать spread и rest
- Используйте spread, когда нужно скопировать массив или объект.
- Используйте spread, чтобы объединить массивы или объекты.
- Используйте spread, чтобы передать массив как список аргументов.
- Используйте rest, когда функция принимает произвольное количество аргументов.
- Используйте rest, чтобы отделить часть данных при деструктуризации.
Советы и лучшие практики
Несколько рекомендаций, которые помогут писать чище:
- Не путайте копирование через spread с глубоким копированием.
- При объединении объектов следите за порядком: последние свойства перезаписывают предыдущие.
- Не используйте spread для огромных массивов в функциях вроде
Math.max(...items): можно упереться в лимит аргументов. - Для читаемости называйте rest-переменные во множественном числе:
...items,...users,...args.
Если вы хотите не просто запомнить отдельные операторы, а уверенно собрать базу JavaScript с практикой, посмотрите курс «JavaScript с Нуля до Гуру 2.0» — понятный путь от основ к уверенной разработке. Он хорошо подойдёт тем, кто хочет системно закрыть пробелы и писать код осознанно.
Итог
Spread и rest оператор в JavaScript — это один синтаксис ..., но два разных сценария. Spread раскрывает данные, rest собирает их. Освоив эти приёмы, вы сможете проще работать с массивами, объектами, функциями и деструктуризацией — а код станет короче и понятнее.
-
Создано 05.08.2026 17:00:41
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.