Leaderboard
Javascript May 23, 2026
Javascript Array Copy Reference Vs Spread

JavaScript Array Cloning — Which Approach is Correct?

This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Array Copy Reference Vs Spread and improve your technical interview readiness.

// Option A
const copy1 = original

// Option B
const copy2 = [...original]
A Option A — simpler and faster
B Option B — creates an independent copy
C Both do the same thing
D Neither works for arrays

Detailed Explanation

Why This Question Matters

If you've ever spent three hours debugging a state change in React or wondering why a variable changed its value when you "didn't touch it," you've likely run into the difference between reference and value.

In JavaScript, copying an array isn't as straightforward as copying a string or a number. Because arrays are objects, they behave differently in memory. New developers often assume that using the equals sign (=) creates a new copy of the data. In reality, it just creates a new pointer to the same spot in memory.

Getting this wrong leads to "mutation bugs"—where changing one array accidentally breaks another part of your app. It's a classic rite of passage for JS developers.

Understanding the Code

Let's look at the two options provided in the challenge:

// Option A
const copy1 = original

// Option B
const copy2 = [...original]

In Option A, we aren't copying the array at all. We are assigning the reference of original to copy1. Think of it like this: the array is a house, and the variable is the address. Option A doesn't build a second house; it just writes the same address on a different piece of paper. If you go to that address and paint the door red, the door is red for everyone who has that address.

Option B uses the spread operator (...). This tells JavaScript to iterate through the original array and "spread" its elements into a brand new array literal []. This actually builds a second house that looks exactly like the first one. If you paint the door of copy2 red, the original house remains untouched.

Finding the Correct Answer

The correct answer is Option B.

Here is what happens when we actually run these in a console:

const original = [1, 2, 3];

// Option A: Reference assignment
const copy1 = original;
copy1.push(4);
console.log(original); // [1, 2, 3, 4] - Wait, what?

// Option B: Shallow copy via spread
const copy2 = [...original];
copy2.push(5);
console.log(original); // [1, 2, 3, 4] - The original stays safe.

Option A fails because copy1 and original are just two names for the exact same object. Any method that mutates the array (like .push(), .pop(), or direct index assignment) will affect both variables.

Option B works because it creates a shallow copy. It allocates a new block of memory and fills it with the values from the original.

Common Mistakes Developers Make

The biggest trap here is the "Shallow Copy" limitation. The spread operator is great for arrays of primitives (numbers, strings, booleans), but it doesn't go deep.

If your array contains other arrays or objects, the spread operator only copies the *references* to those inner objects.

const original = [{ name: 'Alice' }];
const copy = [...original];

copy[0].name = 'Bob';
console.log(original[0].name); // 'Bob'

In the example above, copy is a new array, but the object inside it is still the same object from the original array. This is where developers get tripped up in production. If you have nested data, a simple spread isn't enough; you'd need a deep clone (using structuredClone() in modern browsers or a library like Lodash).

Another common mistake is using Array.prototype.slice(). While original.slice() also creates a shallow copy and is technically correct, the spread operator has become the industry standard because it's more readable and concise.

Real-World Usage

In modern frontend development, this isn't just a "trivia" question—it's a fundamental requirement for state management.

If you're using React, you cannot mutate state directly. If you have an array of todos in your state and you want to add a new one, doing state.push(newTodo) will likely fail to trigger a re-render because React compares the old state and the new state by reference. Since the reference hasn't changed, React thinks nothing happened.

The correct pattern in a React reducer or useState hook is:

setTodos(prevTodos => [...prevTodos, newTodo]);

By spreading the old state into a new array, you create a new reference. React sees that the reference has changed and knows it needs to update the UI. This pattern is the backbone of "immutability" in JavaScript.

Key Takeaways

- Assignment (=) does not copy objects or arrays. It copies the reference (the memory address).
- The spread operator (...) creates a shallow copy. It's the go-to for simple arrays.
- Watch out for nested data. Shallow copies don't protect objects inside arrays.
- Immutability is key. Especially in frameworks like React, creating new array references instead of mutating old ones is the only way to ensure your app behaves predictably.

Why this matters

Understanding Array Copy Reference Vs Spread is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.

📝
Reviewed by CodeShot Editorial
Every challenge is code-reviewed by senior developers to ensure accuracy and real-world relevance. Learn more.

Ready for your shot?

Join thousands of developers solving one logic puzzle every morning.

Solve Today's Challenge →