Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Оператор spread і rest». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Три крапки `...` це один синтаксис із двома протилежними ролями: spread розпаковує масив або об'єкт на окремі елементи, а rest збирає решту елементів назад у масив або об'єкт.** Яку роль обрати, вирішує контекст: у літералі масиву чи об'єкта та у виклику функції це spread, у параметрах функції та в деструктуризації це rest. Обидві операції поверхневі (shallow), тому вкладені структури лишаються спільними за посиланням. ```javascript const nums = [1, 2, 3]; const copy = [0, ...nums]; // spread: розпакували const [head, ...tail] = copy; // rest: зібрали залишок console.log(copy, head, tail); // [0, 1, 2, 3] 0 [1, 2, 3] ``` **Ключове:** spread розгортає, rest збирає; вирішує позиція, а копія завжди поверхнева.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Оператор `...` це один синтаксис із двома ролями: spread (розпакування) розгортає ітерований об'єкт або властивості об'єкта на окремі елементи, а rest (залишок) збирає решту елементів в один масив чи об'єкт.** Роль визначає не сам оператор, а місце, де він стоїть: у літералі та у виклику функції це spread, у параметрах функції та в деструктуризації це rest. ## Теорія ### TL;DR - `...` у літералі або виклику розгортає значення: `[...arr]`, `{...obj}`, `sum(...nums)`. - `...` у деструктуризації або в списку параметрів збирає залишок: `[a, ...rest]`, `function fn(...args)`. - Spread робить поверхневу копію (shallow copy): вкладені об'єкти та масиви копіюються за посиланням. - Spread по об'єктах зливає властивості, і пізніший ключ перезаписує раніший. - Це сучасна заміна `concat`, `Object.assign` і `Array.prototype.slice.call(arguments)`. ### Швидкий приклад ```javascript const numbers = [1, 2, 3]; const moreNumbers = [0, ...numbers, 4, 5]; // spread: розпакували масив console.log(moreNumbers); // [0, 1, 2, 3, 4, 5] const [first, ...rest] = moreNumbers; // rest: зібрали залишок console.log(first); // 0 console.log(rest); // [1, 2, 3, 4, 5] ``` ### Spread: розпакування масивів Spread використовується для розпакування (розкриття) масиву чи об'єкта на окремі елементи. ```javascript const numbers = [1, 2, 3]; const moreNumbers = [0, ...numbers, 4, 5]; console.log(moreNumbers); // [0, 1, 2, 3, 4, 5] ``` Тут `...numbers` «розкрив» масив `[1, 2, 3]` усередину нового масиву. Копіювання масивів: ```javascript const arr1 = [1, 2, 3]; const arr2 = [...arr1]; console.log(arr2); // [1, 2, 3] console.log(arr1 === arr2); // false (новий масив) ``` Це поверхнева копія (shallow copy): новим є лише зовнішній масив. Об'єднання масивів: ```javascript const a = [1, 2]; const b = [3, 4]; const c = [...a, ...b]; console.log(c); // [1, 2, 3, 4] ``` ### Spread у викликах функцій У виклику функції spread перетворює масив на список окремих аргументів. ```javascript function sum(a, b, c) { return a + b + c; } const nums = [1, 2, 3]; console.log(sum(...nums)); // 6 ``` > `...nums` перетворює `[1, 2, 3]` на `sum(1, 2, 3)`. ### Spread з об'єктами Той самий синтаксис копіює власні перелічувані властивості з одного об'єкта в інший. ```javascript const user = { name: 'Alex', age: 25 }; const newUser = { ...user, city: 'Paris' }; console.log(newUser); // { name: 'Alex', age: 25, city: 'Paris' } ``` Якщо ключі збігаються, пізніше значення перезаписує раніше: ```javascript const merged = { a: 1, ...{ a: 2, b: 3 } }; console.log(merged); // { a: 2, b: 3 } ``` ### Rest: збирання залишку Rest працює у зворотний бік: він не розпаковує, а збирає елементи, що залишилися, у масив або об'єкт. У масивах: ```javascript const [first, ...rest] = [1, 2, 3, 4]; console.log(first); // 1 console.log(rest); // [2, 3, 4] ``` В об'єктах: ```javascript const user = { name: 'Alex', age: 25, city: 'Paris' }; const { name, ...info } = user; console.log(name); // Alex console.log(info); // { age: 25, city: 'Paris' } ``` У функціях: ```javascript function sum(...numbers) { return numbers.reduce((a, b) => a + b, 0); } console.log(sum(1, 2, 3, 4)); // 10 ``` `...numbers` збирає всі аргументи функції у справжній масив, на відміну від псевдомасиву `arguments`. ### Spread проти rest і що це замінило | Особливість | Spread | Rest | | --- | --- | --- | | Що робить | Розпаковує | Збирає | | Де використовується | У виклику функції, при створенні масиву або об'єкта | В оголошенні функції або в деструктуризації | | Приклад | `[...arr]`, `{...obj}`, `fn(...args)` | `function fn(...args)`, `[a, ...rest]` | Приклади «до і після»: | До ES6 | З ES6 | | --- | --- | | `arr1.concat(arr2)` | `[...arr1, ...arr2]` | | `Object.assign({}, obj1, obj2)` | `{...obj1, ...obj2}` | | `Array.prototype.slice.call(arguments)` | `(...args) => {}` | Підсумкова таблиця поведінки: | Контекст | Поведінка `...` | Приклад | | --- | --- | --- | | Spread (розпакування) | Розгортає масив або об'єкт | `[...arr]`, `{...obj}`, `sum(...nums)` | | Rest (залишок) | Збирає залишок елементів | `[a, ...rest]`, `function fn(...args)` | ### Типові помилки 1. **Вважати spread глибоким копіюванням.** Spread і rest поверхневі: вкладені об'єкти та масиви копіюються за посиланням, тож зміна вкладеного поля в копії видно в оригіналі. ```javascript const obj = { nested: { a: 1 } }; const copy = { ...obj }; copy.nested.a = 2; console.log(obj.nested.a); // 2, а не 1 ``` Для глибокої копії потрібен `structuredClone(obj)` або ручний обхід структури. 2. **Використовувати `...` без контексту деструктуризації.** Запис `const ...rest = arr;` це синтаксична помилка; правильно `const [a, ...rest] = arr;`. 3. **Ставити rest не останнім.** `function fn(...args, last) {}` не компілюється: rest-параметр може бути лише останнім, бо він забирає все, що лишилося. 4. **Забувати про порядок ключів у spread об'єктів.** `{ ...defaults, ...options }` і `{ ...options, ...defaults }` дають різний результат, бо перемагає той об'єкт, що стоїть правіше. 5. **Плутати `...args` з `arguments`.** `arguments` це псевдомасив, якого немає у стрілкових функціях; rest-параметр завжди дає справжній масив із методами `map`, `filter`, `reduce`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.