Skip to main content
โšก Calmops

Spread Operator and Rest Parameters

Spread Operator and Rest Parameters

The spread operator (...) and rest parameters are powerful features for working with arrays, objects, and function arguments.

Spread Operator

The spread operator expands an iterable into individual elements.

Spreading Arrays

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

// Without spread
const combined1 = arr1.concat(arr2);

// With spread
const combined2 = [...arr1, ...arr2];
console.log(combined2); // [1, 2, 3, 4, 5, 6]

Adding Elements

const arr = [1, 2, 3];

const withStart = [0, ...arr];
console.log(withStart); // [0, 1, 2, 3]

const withEnd = [...arr, 4];
console.log(withEnd); // [1, 2, 3, 4]

const withMiddle = [1, ...arr, 5];
console.log(withMiddle); // [1, 1, 2, 3, 5]

Copying Arrays

const original = [1, 2, 3];

// Shallow copy
const copy = [...original];
console.log(copy); // [1, 2, 3]
console.log(copy === original); // false (different arrays)

Spreading Strings

const str = "hello";

const chars = [...str];
console.log(chars); // ["h", "e", "l", "l", "o"]

Spreading Objects

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

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

Overriding Properties

const defaults = { host: "localhost", port: 3000, ssl: false };
const config = { port: 8080, ssl: true };

const final = { ...defaults, ...config };
console.log(final); // { host: "localhost", port: 8080, ssl: true }

Copying Objects

const original = { name: "Alice", age: 30 };

// Shallow copy
const copy = { ...original };
console.log(copy === original); // false

Rest Parameters

Rest parameters collect multiple arguments into an array.

Basic Rest Parameters

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

console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15

Mixed Parameters

function greet(greeting, ...names) {
    return `${greeting} ${names.join(" and ")}!`;
}

console.log(greet("Hello", "Alice")); // "Hello Alice!"
console.log(greet("Hi", "Bob", "Charlie")); // "Hi Bob and Charlie!"

Rest Must Be Last

// Correct
function test(a, b, ...rest) {
    console.log(a, b, rest);
}

// Error - rest must be last
// function test(...rest, a, b) { }

Rest in Arrow Functions

const sum = (...numbers) => numbers.reduce((a, b) => a + b, 0);

console.log(sum(1, 2, 3, 4)); // 10

Practical Examples

Function with Variable Arguments

function createList(...items) {
    return items.map((item, index) => `${index + 1}. ${item}`);
}

console.log(createList("Learn", "Practice", "Master"));
// ["1. Learn", "2. Practice", "3. Master"]

Merging Multiple Objects

function merge(...objects) {
    return Object.assign({}, ...objects);
}

const obj1 = { a: 1 };
const obj2 = { b: 2 };
const obj3 = { c: 3 };

console.log(merge(obj1, obj2, obj3)); // { a: 1, b: 2, c: 3 }

Removing Duplicates

const arr = [1, 2, 2, 3, 3, 3, 4];
const unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3, 4]

Flattening Arrays

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

// Or with flat()
console.log(nested.flat()); // [1, 2, 3, 4, 5, 6]

Passing Array as Arguments

function multiply(a, b, c) {
    return a * b * c;
}

const numbers = [2, 3, 4];
console.log(multiply(...numbers)); // 24

Combining Spread and Rest

function logArgs(first, ...rest) {
    console.log("First:", first);
    console.log("Rest:", rest);
}

const args = [1, 2, 3, 4];
logArgs(...args);
// First: 1
// Rest: [2, 3, 4]

Cloning with Modifications

const user = { id: 1, name: "Alice", role: "user" };

// Create admin version
const admin = { ...user, role: "admin" };
console.log(admin); // { id: 1, name: "Alice", role: "admin" }
console.log(user); // { id: 1, name: "Alice", role: "user" } (unchanged)

Collecting Function Arguments

function formatMessage(template, ...values) {
    let result = template;
    values.forEach((value, index) => {
        result = result.replace(`{${index}}`, value);
    });
    return result;
}

console.log(formatMessage("Hello {0}, you are {1} years old", "Alice", 30));
// "Hello Alice, you are 30 years old"

Shallow vs Deep Copy

Shallow Copy

const original = { a: 1, b: { c: 2 } };

// Shallow copy - nested objects are still referenced
const copy = { ...original };
copy.b.c = 99;

console.log(original.b.c); // 99 (affected!)

Deep Copy

const original = { a: 1, b: { c: 2 } };

// Deep copy using JSON
const copy = JSON.parse(JSON.stringify(original));
copy.b.c = 99;

console.log(original.b.c); // 2 (not affected)

Performance Considerations

Spread vs concat()

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

// concat()
const result2 = arr1.concat(arr2);

// Both are similar in performance

Spread vs Object.assign()

// Spread
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const result1 = { ...obj1, ...obj2 };

// Object.assign()
const result2 = Object.assign({}, obj1, obj2);

// Spread is more readable

Common Patterns

Default Parameters with Rest

function request(url, options = {}) {
    const { method = "GET", timeout = 5000, ...headers } = options;
    console.log(method, timeout, headers);
}

request("https://api.example.com", {
    method: "POST",
    timeout: 10000,
    "Content-Type": "application/json"
});

Destructuring with Rest

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

Combining Arrays and Objects

const arr = [1, 2, 3];
const obj = { a: 1, b: 2 };

const combined = {
    items: [...arr],
    config: { ...obj }
};

console.log(combined);
// { items: [1, 2, 3], config: { a: 1, b: 2 } }

Summary

  • Spread operator: expands iterables into elements
  • Arrays: combine, copy, add elements
  • Objects: merge, copy, override properties
  • Rest parameters: collect arguments into array
  • Must be last: rest parameters must be final parameter
  • Shallow copy: nested objects still referenced
  • Performance: similar to traditional methods

Official Documentation

Next Steps

  1. Destructuring: Arrays and Objects
  2. Array Methods: map, filter, reduce, forEach
  3. Arrow Functions and Function Expressions

Comments