Skip to main content

Command Palette

Search for a command to run...

Rest , Spread ,Deep Copy , Shallow Copy...

Published
•4 min read•View as Markdown
Rest , Spread ,Deep Copy ,  Shallow Copy...

Mastering Rest and Spread Operators in JavaScript (With Deep vs Shallow Copy)

JavaScript is full of powerful features, and two of the most useful are the Rest (...rest) and Spread (...spread) operators. These operators simplify working with arrays, objects, and function arguments. However, their behavior can lead to confusion when dealing with shallow and deep copies. In this article, we’ll break down these concepts with practical examples.


What is the Rest Operator (...rest)?

The rest operator (...) collects multiple values into an array. It is commonly used in function parameters and object/array destructuring.

Example 1: Using Rest in Function Parameters

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

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

How it works? The ...numbers parameter collects all function arguments into an array, allowing us to apply the .reduce() method.


Example 2: Rest in Object Destructuring

const person = { name: "John", age: 25, city: "New York" };
const { name, ...rest } = person;

console.log(name); // Output: John
console.log(rest); // Output: { age: 25, city: 'New York' }

The ...rest collects the remaining properties (age and city) into an object.


What is the Spread Operator (...spread)?

The spread operator (...) expands elements of an array, object, or iterable into individual values.

Example 1: Copying an Array

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

console.log(arr2); // Output: [1, 2, 3, 4, 5, 6]

Here, arr1 is expanded inside arr2, effectively copying its elements.


Example 2: Merging Objects

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

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

The spread operator merges both objects into a new one.


Shallow Copy vs. Deep Copy

When working with objects, understanding shallow copy and deep copy is crucial.

Shallow Copy (One-Level Copy)

A shallow copy copies only the first level of an object. If the object contains nested structures, changes to the nested values will reflect in the original object.

Example: Shallow Copy Using Spread Operator

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { ...obj1 };

obj2.b.c = 99;

console.log(obj1.b.c); // Output: 99 (changes reflected)
console.log(obj2.b.c); // Output: 99

Why? The spread operator only copies the outer object. The b property is still referencing the original nested object.


Deep Copy (Fully Cloned)

A deep copy creates a completely independent object. Changes in the copy do not affect the original.

Method 1: Using JSON.parse(JSON.stringify(obj))

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = JSON.parse(JSON.stringify(obj1));

obj2.b.c = 99;

console.log(obj1.b.c); // Output: 2 (original remains unchanged)
console.log(obj2.b.c); // Output: 99

Downside: This method does not work if the object contains functions or undefined values.


Method 2: Using Lodash’s cloneDeep()

const _ = require('lodash');

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = _.cloneDeep(obj1);

obj2.b.c = 99;

console.log(obj1.b.c); // Output: 2 (original unchanged)
console.log(obj2.b.c); // Output: 99

Lodash provides a powerful _.cloneDeep() function for deep copying.


Key Differences: Rest vs. Spread, Shallow vs. Deep Copy

FeatureRest (...rest)Spread (...spread)Shallow CopyDeep Copy
PurposeCollects values into an arrayExpands values into individual elementsCopies first level onlyCopies everything
Use CaseFunction parameters, destructuringFunction arguments, copying, mergingNested objects remain linkedCompletely independent copy
Changes Original?NoNoYes (nested values)No

Conclusion

  • The rest operator (...rest) gathers multiple elements into an array.

  • The spread operator (...spread) expands elements into individual values.

  • Shallow copy (...spread) only copies the first level, keeping nested references intact.

  • Deep copy (JSON.parse(), _.cloneDeep()) ensures full independence of objects.

Now that you know these concepts, go ahead and use them in your JavaScript projects.

Did you find this helpful? Share your thoughts in the comments.