🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·
JavaScript

Spread and Rest operators

📚 What are Spread and Rest? The ... operator does two different but related things. As spread, it expands an array or object: [...arr] creates a shallow copy, {...obj} merges objects. As rest, it collects remaining arguments into an array: function f(...args) accepts any number of arguments.

8 min 10 XP Lesson 13 of 21
Spread and Rest operators
🌐

Appy Says…

Three dots (...) are one of the most useful things in modern JavaScript. They can copy arrays, merge objects, pass any number of arguments, and collect leftovers. Once you understand spread and rest, you'll use them every day.

📖

What are Spread and Rest?

The ... syntax has two uses depending on context. Spread expands an iterable into individual elements. Rest collects multiple elements into a single array or object.

  • Spread in arrays: [...a, ...b] — merge two arrays
  • Spread in objects: { ...obj, extra: 'value' } — copy + extend
  • Spread in function calls: Math.max(...numbers)
  • Rest in function params: function sum(...nums) { ... } — collect all args
  • Rest in destructuring: const [first, ...rest] = array
  • Spread copies shallowly — nested objects are still shared references
🎮

Think of it like merging Minecraft chests

Spread is like emptying two chests onto the floor and putting everything into a new combined chest. Rest is the opposite — you grab the first item, and everything remaining goes into a new separate chest. Same items, different operations.

⚙️

How It Works

  • 1. [...arr1, ...arr2] — creates a new array with all items from both
  • 2. { ...obj1, ...obj2 } — copies all properties; later keys overwrite earlier ones
  • 3. const [head, ...tail] = [1,2,3,4]head = 1, tail = [2,3,4]
  • 4. function log(first, ...rest) {}rest is an array of all remaining args
  • 5. In React: setState(prev => ({ ...prev, name: 'New' })) — immutable state update
  • 6. Override properties: { ...defaults, ...userPrefs } — user wins
🌍

Real-World Examples

  • Merge playlists: [...myPlaylist, ...friendPlaylist]
  • Update user profile without mutation: { ...user, bio: newBio }
  • Pass array as separate args: console.log(...messages)
  • React state update: setCart(prev => [...prev, newItem])
  • Override config defaults: const config = { ...defaultConfig, ...userConfig }
💡

Key Facts

  • Spread creates a shallow copy — changing nested objects still affects the original
  • For deep cloning use structuredClone(obj) (modern) or JSON.parse(JSON.stringify(obj)) (older trick)
  • Rest must always be the last parameter: function (a, b, ...rest) is valid, but (...rest, a) is not
  • Object.assign({}, obj) is the older equivalent of spread for objects
⚠️

Watch Out!

Spread only copies one level deep. const copy = { ...obj } creates a new object, but if obj.settings is another object, copy.settings still points to the same reference. Modifying nested data in the copy modifies the original too.

📌

Remember

Spread (...) expands into elements; Rest (...) collects into an array. Same syntax, opposite direction depending on context.

What You Learned

  • Spread expands iterables; rest collects multiple values — both use ...
  • Key uses: merging arrays/objects, copying state immutably, variadic functions
  • Unlocks: immutable state updates, config merging, clean React patterns

Key Facts

  • Spread creates a shallow copy — changing nested objects still affects the original
  • For deep cloning use structuredClone(obj) (modern) or JSON.parse(JSON.stringify(obj)) (older trick)
  • Rest must always be the last parameter: function (a, b, ...rest) is valid, but (...rest, a) is not
  • Object.assign({}, obj) is the older equivalent of spread for objects

Real-World Examples

• Merge playlists: <code>[...myPlaylist, ...friendPlaylist]</code> • Update user profile without mutation: <code>{ ...user, bio: newBio }</code> • Pass array as separate args: <code>console.log(...messages)</code> • React state update: <code>setCart(prev => [...prev, newItem])</code> • Override config defaults: <code>const config = { ...defaultConfig, ...userConfig }</code>

Remember

Spread (...) expands into elements; Rest (...) collects into an array. Same syntax, opposite direction depending on context.

Quick Quiz

1 / 2

... in [...arr] is?