Skip to content
beginnerPhase 32 · JavaScript Fundamentals

Spread and Rest

Use spread operator for copying/expanding and rest for parameter gathering.

30m
0 problems
Topic Progress0%

Spread Operator

Spread Operator

The spread operator (...) expands an iterable into individual elements.

Arrays

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

// Concatenation
const combined = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

// Copy
const copy = [...arr1]; // [1, 2, 3]

// Add elements
const withNew = [...arr1, 4]; // [1, 2, 3, 4]
const withNewAtStart = [0, ...arr1]; // [0, 1, 2, 3]

Objects

const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };

// Merge
const merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }

// Copy
const copy = { ...obj1 };

// Override
const updated = { ...obj1, b: 20 }; // { a: 1, b: 20 }

Function Arguments

const numbers = [1, 2, 3, 4, 5];

// Pass array as arguments
Math.max(...numbers); // 5
console.log(...numbers); // 1 2 3 4 5

Strings

const str = 'hello';
const chars = [...str]; // ['h', 'e', 'l', 'l', 'o']

Objects with Same Keys

const defaults = { color: 'red', size: 'medium' };
const custom = { color: 'blue' };

// custom overrides defaults
const result = { ...defaults, ...custom };
// { color: 'blue', size: 'medium' }

Spread vs Object.assign

// Object.assign (mutates target)
const target = { a: 1 };
Object.assign(target, { b: 2 });

// Spread (creates new)
const original = { a: 1 };
const copy = { ...original, b: 2 };

Rest Parameters

Rest Parameters

Rest parameters collect remaining elements into an array.

In Function Parameters

function sum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}

sum(1, 2, 3);    // 6
sum(1, 2, 3, 4); // 10

With Other Parameters

function log(level, ...messages) {
  console.log(level, ...messages);
}

log('INFO', 'Server', 'started', 'on', 'port', '3000');

In Destructuring

const [first, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest);  // [2, 3, 4, 5]

const { name, ...details } = { name: 'John', age: 30, city: 'NYC' };
console.log(name);    // "John"
console.log(details); // { age: 30, city: 'NYC' }

Arguments Object vs Rest

// Old: arguments object
function oldSum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

// Modern: rest parameters
function newSum(...numbers) {
  return numbers.reduce((total, n) => total + n, 0);
}

Rest in Arrow Functions

const sum = (...numbers) => 
  numbers.reduce((total, n) => total + n, 0);

sum(1, 2, 3); // 6

Rest Must Be Last

// Correct
function fn(a, b, ...rest) { }

// Error
function fn(...rest, a, b) { }

Practical Examples

Practical Examples

Immutability Patterns

// Add to array
const arr = [1, 2, 3];
const newArr = [...arr, 4]; // [1, 2, 3, 4]

// Remove from array
const index = 1;
const withoutItem = arr.filter((_, i) => i !== index);

// Update in array
const updated = arr.map(item => 
  item === 2 ? 20 : item
);

// Add to object
const obj = { a: 1, b: 2 };
const newObj = { ...obj, c: 3 };

// Remove from object
const { a, ...rest } = obj; // rest is { b: 2 }

// Update in object
const updatedObj = { ...obj, b: 20 };

shallow Clone Patterns

// Array clone
const clone = [...original];

// Object clone
const clone = { ...original };

// Shallow clone (top level only)
const shallow = { ...original };
deep.nested.value = 'changed'; // Affects original!

Function Arguments

// Pass array as arguments
const args = [1, 2, 3];
Math.max(...args);

// Combine with other args
function log(prefix, ...messages) {
  console.log(prefix, ...messages);
}

Array Flattening

const nested = [[1, 2], [3, 4], [5]];
const flat = nested.flat(); // [1, 2, 3, 4, 5]

// Manual flatten with spread
const flat = [].concat(...nested);

Object Merging

// Deep merge (simple)
deepMerge(obj1, obj2);

function deepMerge(target, source) {
  return {
    ...target,
    ...Object.fromEntries(
      Object.entries(source).map(([key, val]) => [
        key,
        typeof val === 'object' && val !== null
          ? deepMerge(target[key] || {}, val)
          : val
      ])
    )
  };
}

Performance Considerations

// Spread creates new objects/arrays
const arr = [1, 2, 3];
const copy = [...arr]; // New array!

// For large arrays, consider:
const copy = arr.slice(); // Slightly faster

// For objects:
const copy = Object.assign({}, obj); // Or spread

Practice Problems

0/3solved
Build Spread and Rest Component

Create a reusable React component implementing Spread and Rest. Include proper state management and accessibility.

Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where needed
Spread and Rest Testing

Write unit and integration tests for Spread and Rest using React Testing Library.

Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility tests
Spread and Rest Performance

Optimize Spread and Rest for performance. Consider memoization, code splitting, and bundle size.

Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysis

Quiz

1. What does the spread operator do?

Question 1 options

2. What is the difference between spread and rest?

Question 2 options

3. What must rest parameters be in a function?

Question 3 options

4. How do you copy an array with spread?

Question 4 options

5. What happens with duplicate keys when spreading objects?

Question 5 options

Flashcards

Question

What does ... (spread) do?

Answer

Expands an iterable into individual elements: [1, ...[2,3]] = [1,2,3]

Question

What do rest parameters do?

Answer

Collect remaining function arguments into an array: function sum(...nums) {}

Question

What is the difference between spread and rest?

Answer

Spread expands iterables. Rest collects into arrays. Same syntax, opposite purposes.

Question

How do you shallow copy an object with spread?

Answer

const copy = { ...original };

Question

Can rest parameters be first in a function?

Answer

No, rest parameters must be the last parameter in a function signature.

Revision Notes

Key Takeaways

  • 1.Spread expands, rest collects
  • 2.Both use the same ... syntax
  • 3.Rest must be last in function parameters
  • 4.Spread creates shallow copies
  • 5.Later object keys overwrite earlier ones

Interview Tips

  • Explain the difference between spread and rest
  • Know how to use spread for copying
  • Understand rest in function parameters
  • Be able to merge objects with spread

Cheat Sheet

Spread and Rest Cheat Sheet

Spread (...)

// Arrays
const arr = [...arr1, ...arr2];
const copy = [...arr];

// Objects
const obj = { ...obj1, ...obj2 };
const copy = { ...obj };

// Function args
Math.max(...numbers);

Rest (...)

// Function parameters
function sum(...nums) { }

// Destructuring
const [first, ...rest] = arr;
const { name, ...details } = obj;

Key Points

  • Spread: expands iterables
  • Rest: collects into arrays
  • Rest must be last parameter
  • Both create shallow copies
  • Later values overwrite earlier in objects