The Spread Operator (...), introduced for objects in ES2018, allows you to copy properties from one object into another. It provides a concise, declarative syntax for shallow cloning, merging datasets, and updating state without mutating the original object.

1. Basic Syntax and Usage

The operator “unpacks” the key-value pairs of an object. It is most commonly used within an object literal to create a new object.

JavaScript
const user = { name: 'Alice', age: 25 };

// Cloning the object
const userCopy = { ...user }; 

console.log(userCopy); // { name: 'Alice', age: 25 }

2. Merging Objects

You can spread multiple objects into a single new object. If the objects share the same keys, the last one spread will overwrite the previous values.

JavaScript
const defaults = { theme: 'light', fontSize: 14 };
const userSettings = { theme: 'dark' };

const finalConfig = { ...defaults, ...userSettings };

console.log(finalConfig); // { theme: 'dark', fontSize: 14 }

3. The “Shallow Copy” Constraint

It is vital to remember that the spread operator performs a shallow copy. It copies the top-level primitives by value, but for nested objects or arrays, it only copies the reference.

The Side Effect Risk:

JavaScript
const original = { id: 1, info: { status: 'active' } };
const clone = { ...original };

// Modifying a nested property in the clone...
clone.info.status = 'offline';

// ...also affects the original!
console.log(original.info.status); // 'offline'

4. Advanced Use Cases

A. Merging Multiple Objects

You can spread an unlimited number of objects into one. This is common in state management patterns (like Redux or React’s useState).

JavaScript
const part1 = { a: 1 };
const part2 = { b: 2 };
const part3 = { c: 3 };

const combined = { ...part1, ...part2, ...part3 };

B. Immutably Updating Nested State

Since state in modern frameworks should be treated as immutable, the spread operator is used to “create a new version” of an object without modifying the old one.

JavaScript
const state = { id: 1, meta: { status: "pending" } };

// Correct way to update nested properties immutably
const newState = {
  ...state,
  meta: {
    ...state.meta,
    status: "completed"
  }
};

C. Conditionally Adding Properties

You can use the spread operator in combination with short-circuit evaluation (&&) to conditionally include properties in an object.

JavaScript
const isPremium = true;
const user = {
  name: "Sarah",
  ...(isPremium && { badge: "👑" })
};

5. Rest Properties

The spread operator’s “twin” is the Rest Pattern, used during destructuring. It allows you to extract specific properties from an object and collect all remaining properties into a new variable.

JavaScript
const settings = {
  theme: "dark",
  volume: 80,
  notifications: true,
  autoUpdate: false
};

// Destructure theme and volume, put the "rest" in others
const { theme, volume, ...others } = settings;

console.log(theme);  // "dark"
console.log(others); // { notifications: true, autoUpdate: false }

6. Performance and Edge Cases

Null and Undefined

One of the safety features of the object spread operator is that it ignores null and undefined without throwing an error. This makes it safer for merging optional configurations.

JavaScript
const config = null;
const finalConfig = { default: true, ...config }; 
// Result: { default: true } (No error thrown!)

Prototypal Properties

The spread operator only copies own enumerable properties. Properties inherited through the prototype chain are ignored.

JavaScript
const proto = { inherited: "yes" };
const obj = Object.create(proto);
obj.own = "no";

const spreaded = { ...obj };
console.log(spreaded.inherited); // undefined
console.log(spreaded.own);       // "no"

Categorized in:

Javascript,