JavaScript ECMAScript 2024 ·
✓ verified by execution on
The Illusion of Copying
When working with arrays in JavaScript, you will often find yourself needing to create a duplicate of an existing array. Perhaps you want to modify a list of names without permanently changing the original list, or perhaps you want to preserve a historical record of your data before applying a series of transformations.
However, a very common misconception among developers learning JavaScript is assuming that the equals sign (=) creates a brand new copy of an array. In reality, arrays in JavaScript are treated as reference types. When you assign an existing array to a new variable, you are not actually copying the contents of the array into a new space in memory. Instead, you are simply copying the reference (the address or pointer) to the exact same array in memory. Both variables now point to the identical location. If you modify one, you inadvertently modify the other. Let’s observe this dangerous behavior in action.
javascript
const original = [1, 2, 3];const fakeCopy = original;fakeCopy.push(4);console.log(original);
Output
[ 1, 2, 3, 4 ]
Your output
As you can see from the output, even though we pushed the number 4 to fakeCopy, the original array was also modified! This side effect is the root of many bugs.
Memory Diagram: References vs Copies
Here is a visual representation of how a shallow copy creates a completely new array structure in memory, while assigning the reference just points a new variable name to the same existing box.
Assignment copies the reference, so both names point at one array. The spread operator builds a genuinely new array, which is why only the second is safe to modify.
The Spread Operator to the Rescue
To solve this problem and safely clone our data, JavaScript introduced a powerful feature in ES6 called the Spread syntax. It is represented by three consecutive dots (...).
The spread syntax effectively unpacks or “spreads out” an iterable object (like an array) into its individual elements. When you place the spread operator inside a new set of square brackets [], JavaScript takes all the individual items from the original array and drops them into a completely new array literal. This creates a true, independent copy in memory. Modifying the new array will no longer have any impact on the original array, allowing you to manipulate your data with confidence.
javascript · visualize
const original = [1, 2, 3];const realCopy = [...original];realCopy.push(4);console.log(original);console.log(realCopy);
Merging Multiple Arrays Together
The spread operator isn’t just useful for cloning single arrays; it is also the most modern and elegant way to combine multiple arrays together. Because the spread operator unpacks elements, you can use it multiple times within the same array literal.
Imagine you have two separate lists of seasonal items that you want to merge into a single master list. Instead of writing complex loops or using older methods like concat(), you can effortlessly place them side by side using the spread syntax.
The flexibility of the spread operator extends even further. Not only can you merge arrays, but you can also mix spread arrays with individual, hardcoded elements. You can seamlessly inject items at the beginning, in the middle, or at the end of the new array.
By inserting spread elements in the middle of a new array literal alongside newly defined values, you can build up complex arrays dynamically and cleanly.
While we have focused primarily on arrays, it’s worth noting that the spread operator is extremely versatile and works with other data structures as well. For example, it is just as common to use the spread syntax on object literals.
In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the newly created object. This allows you to clone objects or merge multiple objects together just as easily as we did with arrays.
There is one extremely important detail you must understand about the spread operator: it only creates a shallow copy.
Spread syntax effectively goes one level deep. It copies the top-level elements of the array. But what happens if your array contains other arrays, or if it contains objects? In that scenario, the spread operator copies the references to those nested items, rather than duplicating the nested items themselves. Therefore, if you mutate a deeply nested object inside your cloned array, the change will reflect in the original array. Keep this in mind when working with multidimensional data.
Predict the outputjavascript
Read the code. What exactly will it print? Commit to an answer before you look.
A developer tried to make a backup copy of their `scores` array before modifying it, but the `backup` array also got modified! Fix the code so that the `backup` array remains a true, independent copy.
This code runs. It just does the wrong thing. Read it, find the defect,
fix it — the tests below decide when you are right.
javascript
Test 1 — expects "3\n"
Need a hint? (−25% XP)
Assigning an array to a new variable just copies the reference. Use the spread operator inside an array literal `[...array]` to create a true, independent shallow copy.