JavaScript Spread Operator for Arrays and Objects

The JavaScript spread operator (...), introduced in ES6, provides a clean and concise syntax for expanding iterable elements like arrays and string characters, as well as copying enumerable properties from objects. This article explains how the spread operator operates across both arrays and objects, covering key use cases such as cloning, merging, function arguments, and property overriding.

Understanding the Spread Operator Syntax

The spread operator is written as three consecutive dots (...). When applied to an iterable or an object, it unpacks its individual elements or key-value pairs into a new context, such as inside an array literal, an object literal, or a function call.

Spread Operator with Arrays

When used with arrays, the spread operator unpacks array elements individually.

1. Copying Arrays

Creating a shallow copy of an array without mutating the original:

const original = [1, 2, 3];
const copy = [...original];

console.log(copy); // [1, 2, 3]

2. Combining and Merging Arrays

Concatenating multiple arrays or inserting elements at arbitrary positions:

const fruits = ['apple', 'banana'];
const vegetables = ['carrot', 'spinach'];

const combined = [...fruits, 'orange', ...vegetables];
console.log(combined); // ['apple', 'banana', 'orange', 'carrot', 'spinach']

3. Function Arguments

Passing an array as individual arguments to functions that expect separate parameters:

const numbers = [10, 50, 8, 25];
const max = Math.max(...numbers);

console.log(max); // 50

4. Converting Iterables to Arrays

Converting other iterable objects, such as strings, Sets, or NodeLists, into standard arrays:

const word = "hello";
const letters = [...word];

console.log(letters); // ['h', 'e', 'l', 'l', 'o']

Spread Operator with Objects

When used inside object literals, the spread operator copies own enumerable properties from one object to another.

1. Copying Objects

Creating a shallow copy of an object:

const user = { name: 'Alice', age: 28 };
const userCopy = { ...user };

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

2. Merging Objects

Combining properties from multiple objects into a single object:

const personalInfo = { name: 'Bob', age: 32 };
const jobInfo = { title: 'Developer', company: 'TechCorp' };

const profile = { ...personalInfo, ...jobInfo };
console.log(profile);
// { name: 'Bob', age: 32, title: 'Developer', company: 'TechCorp' }

3. Overriding and Adding Properties

When merging objects or copying, properties that appear later in the declaration overwrite earlier matching keys:

const defaults = { theme: 'light', showSidebar: true, fontSize: 14 };
const userSettings = { theme: 'dark', fontSize: 16 };

const settings = { ...defaults, ...userSettings, autoSave: true };
console.log(settings);
// { theme: 'dark', showSidebar: true, fontSize: 16, autoSave: true }

Important Distinction: Shallow Copying

The spread operator only creates a shallow copy for both arrays and objects. If an array contains nested arrays or an object contains nested objects, only references to those nested structures are copied, meaning changes to nested data will reflect in both copies.

const original = { details: { role: 'admin' } };
const clone = { ...original };

clone.details.role = 'user';
console.log(original.details.role); // 'user' (mutated)

To create a deep copy, native methods like structuredClone() or libraries like Lodash should be used instead.