Rest and Spread

The ... operator does two different things depending on context: spread expands, rest collects.

Spread — expand arrays/objects

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

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

const copy = [...arr1]  // shallow copy

// With Math
Math.max(...arr1)  // 3

// Spread objects
const obj1 = { a: 1, b: 2 }
const obj2 = { b: 3, c: 4 }
const merged = { ...obj1, ...obj2 }
// { a: 1, b: 3, c: 4 }  (obj2.b overrides obj1.b)

Rest — collect remaining arguments

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

sum(1, 2, 3)     // 6
sum(1, 2, 3, 4, 5)  // 15

// Rest must be last parameter
function first(a, b, ...rest) {
  console.log(a)    // first arg
  console.log(b)    // second arg
  console.log(rest) // remaining args array
}

first(1, 2, 3, 4, 5)
// 1
// 2
// [3, 4, 5]