JavaScript Mutable Reference Error
This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Reference Vs Value and improve your technical interview readiness.
const x = [1, 2, 3]
const y = x
y.push(4)
console.log(x.length)
Detailed Explanation
Why This Question Matters
If you've ever spent three hours debugging a state change in React or wondered why a variable changed its value "randomly" in a different file, you've likely run into the issue of reference vs. value.
In JavaScript, how the language handles different data types is one of those things that seems intuitive until it isn't. Most beginners assume that assigning a variable to another creates a copy. It doesn't. This specific challenge tests whether you understand how JavaScript manages memory for objects and arrays. If you don't get this, you'll end up introducing bugs that are incredibly hard to track down because the "source of truth" for your data is being mutated from a place you didn't expect.
Understanding the Code
Let's look at the snippet again:
At first glance, it looks like we have two arrays. But that's the trap.
When you write const x = [1, 2, 3], JavaScript doesn't actually store the array values directly inside the variable x. Instead, it creates the array in memory (the heap) and stores a reference (a memory address) in x. Think of x not as the box containing the numbers, but as a piece of paper with the address of the box written on it.
Then comes the line const y = x.
Here, you aren't copying the array. You are copying the *reference*. Now, both x and y are pointing to the exact same spot in memory. They are two different names for the same physical object.
When we call y.push(4), we are telling JavaScript: "Go to the address stored in y and add the number 4 to that array." Since x points to that same address, the change is reflected when we check x.length.
Finding the Correct Answer
The correct answer is Option B (which is 4).
Here is why the other logic fails:
- Thinking it's 3: Some developers assume const y = x creates a shallow copy. If it did, y would be a new array [1, 2, 3], and pushing to it wouldn't affect x. But in JS, the assignment operator = does not clone objects or arrays.
- Thinking it's an error: Some might think const prevents the array from being changed. const prevents reassignment (you can't do x = [5, 6]), but it does not make the object itself immutable. You can still push, pop, or change properties of a const object.
Common Mistakes Developers Make
The biggest mistake is confusing assignment with cloning.
I see this all the time in junior code: someone tries to "backup" an array before filtering it, does const backup = originalArray, and then proceeds to mutate the original, wondering why their backup is also changed.
Another trip-wire is the "mutation" mindset. In modern frameworks like React or Redux, mutating an array directly (like using .push()) is a cardinal sin. Because the reference doesn't change, the framework thinks the state is the same and refuses to re-render the component. This is why you'll see experienced devs using the spread operator [...] or .map() and .filter()βthese methods return a *new* array rather than modifying the existing one.
Real-World Usage
In a production environment, understanding references is critical for performance and state management.
Imagine you have a global configuration object for your app. If you pass that object into a helper function and that function modifies a property, it modifies it for the entire application. This is called a side effect.
To avoid this, we use immutability. Instead of const y = x, we do:
By creating a new reference, we isolate the data. This is the foundation of how "Undo/Redo" features work and how time-travel debugging is possible in tools like Redux DevTools. You aren't changing the old state; you're creating a new version of it.
Key Takeaways
- Primitives (strings, numbers, booleans) are passed by value. If you copy a string, you have two independent strings.
- Objects and Arrays are passed by reference. Copying them just gives you a second pointer to the same data.
- const protects the binding, not the value. You can't point the variable to a new address, but you can change the contents of the address it already points to.
- When you actually need a copy, use the spread operator [...] or Object.assign() to avoid accidental mutations.
Why this matters
Understanding Reference Vs Value 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.