Різниця між spread і rest
Головна різниця в одному реченні: spread розпаковує елементи (розкриває масив або об'єкт), а rest збирає елементи (пакує залишок у масив або об'єкт). Пишуться вони однаково, трьома крапками, тому розрізняти їх доводиться за позицією у коді, а не за виглядом.
Теорія
TL;DR
- Spread розгортає структуру:
[...arr],{...obj},fn(...args). - Rest пакує залишок:
function fn(...args),[a, ...rest],{ a, ...rest }. - Spread живе в контексті виклику або створення, rest, у контексті оголошення або деструктуризації.
- Результат spread, це окремі елементи; результат rest, це новий масив або об'єкт.
...сам по собі не оператор мови, а частина синтаксису деструктуризації та виклику функції.- Обидва роблять поверхневе копіювання (shallow copy).
Швидкий приклад
function logFirstAndRest(first, ...rest) { // rest збирає
console.log('First:', first);
console.log('Others:', rest);
}
const numbers = [10, 20, 30, 40];
logFirstAndRest(...numbers); // spread розгортає
// Що відбувається:
// logFirstAndRest(10, 20, 30, 40);
// first = 10
// rest = [20, 30, 40]Spread, розпакування даних
Використовується, коли потрібно розгорнути структуру (масив або об'єкт) на окремі елементи.
Приклад з масивом:
const arr = [1, 2, 3];
console.log(...arr); // 1 2 3Копіювання та об'єднання:
const a = [1, 2];
const b = [3, 4];
const merged = [...a, ...b];
console.log(merged); // [1, 2, 3, 4]Приклад з об'єктом:
const user = { name: 'Alex', age: 25 };
const newUser = { ...user, city: 'Paris' };
console.log(newUser); // { name: 'Alex', age: 25, city: 'Paris' }Приклад у виклику функції:
function sum(a, b, c) {
return a + b + c;
}
const nums = [1, 2, 3];
console.log(sum(...nums)); // 6Одне правило: spread розкриває структуру.
Rest, збирання даних
Використовується, коли потрібно зібрати кілька елементів в одну структуру (масив або об'єкт).
Приклад у функціях:
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2, 3, 4)); // 10Тут
...numbersзбирає всі аргументи в масив[1, 2, 3, 4].
Приклад у деструктуризації масиву:
const [first, ...rest] = [1, 2, 3, 4];
console.log(first); // 1
console.log(rest); // [2, 3, 4]Приклад у деструктуризації об'єкта:
const user = { name: 'Alex', age: 25, city: 'Paris' };
const { name, ...info } = user;
console.log(name); // Alex
console.log(info); // { age: 25, city: 'Paris' }Одне правило: rest збирає залишок.
Порівняння віч-на-віч
| Критерій | Spread (...) | Rest (...) |
|---|---|---|
| Дія | Розпаковує значення | Збирає значення |
| Де використовується | У виклику функцій, масивах, об'єктах | У параметрах функцій і деструктуризації |
| Результат | Окремі елементи | Новий масив або об'єкт |
| Приклад з масивом | [...arr] дає 1, 2, 3 | [a, ...rest] дає rest = [2, 3] |
| Приклад з об'єктом | {...obj} | { a, ...rest } |
| Приклад з функцією | sum(...nums) | function sum(...nums) |
Коли вони зустрічаються разом
Найкраще різницю видно там, де обидва працюють в одному рядку коду.
function logFirstAndRest(first, ...rest) {
console.log('First:', first);
console.log('Others:', rest);
}
const numbers = [10, 20, 30, 40];
logFirstAndRest(...numbers);
// Розшифровка: logFirstAndRest(10, 20, 30, 40);
// first = 10
// rest = [20, 30, 40]Тут spread розкриває numbers у момент виклику функції, а rest збирає аргументи вже всередині функції. Просте правило для запам'ятовування: spread, це «розгорни», rest, це «збери».
Типові помилки
-
Шукати різницю в синтаксисі. Символи однакові, різниця виключно контекстна: контекст виклику або створення означає spread, контекст оголошення або деструктуризації означає rest.
-
Називати
...окремим оператором мови. Це не оператор, а частина синтаксису деструктуризації та виклику функції, тому він не працює сам по собі:const ...rest = arr;це синтаксична помилка. -
Очікувати глибокої копії. І spread, і rest копіюють поверхнево, тож вкладені об'єкти лишаються спільними.
javascriptconst state = { user: { name: 'Alex' } }; const copy = { ...state }; copy.user.name = 'Maria'; console.log(state.user.name); // Maria -
Ставити rest-параметр не останнім.
function fn(...args, last) {}не парситься: rest забирає все, що лишилося, тому після нього нічого бути не може. -
Плутати
...argsзarguments. Rest завжди дає справжній масив і працює у стрілкових функціях, аargumentsце псевдомасив, якого в стрілкових функціях немає.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.