Avoiding Unintended Mutations in JavaScript: A Real-World Example

Ishwar Rimal
3 min readDec 21, 2024

--

In JavaScript, unintended mutations can lead to hard-to-debug issues, especially when working with arrays or objects. This article explores a real-world example, demonstrates the problem, and discusses how to resolve it while maintaining clean, immutable code.

Note: This was an issue we faced in one of the production-level systems I worked on, leading to unexpected side effects. Adopting immutability practices resolved the problem and improved the code’s robustness.

The Problem: Unintended Mutation

Let’s start with a scenario where we have two arrays: one representing predefined status information (statusInfo) and another representing a dynamic response (response). Our goal is to map each entry in response to an enriched object from statusInfo, updating the text property if a value exists in the response.

Here’s the initial implementation:

const statusInfo = [
{ status: 'done', color: 'green', text: 'done'},
{ status: 'in-progress', color: 'yellow', text: 'in progress'}
];
const response = [
{ status: 'done' },
{ status: 'done', value: 'No action required' },
{ status: 'in-progress' }
]; //Some data from api
const result = [];response.forEach((currentData) => {
const { status, value } = currentData;
const currentStatus = statusInfo.find(info => info.status === status);
if (value) {
currentStatus.text = value;
}
result.push(currentStatus);
});
console.log(result);
console.log(statusInfo);

The Issue

At first glance, this code seems fine. However, if you inspect the statusInfo array after execution, you’ll notice it has been mutated:

console.log(statusInfo);
// Output:
// [
// { status: 'done', color: 'green', text: 'No action required' },
// { status: 'in-progress', color: 'yellow', text: 'in progress' }
// ]

The text property of the done status was updated within statusInfo. This happened because objects in JavaScript are passed by reference, and modifying currentStatus.text directly affected the original statusInfo object.

This mutation can cause unintended side effects, especially if statusInfo is used elsewhere in the code. Such issues are often difficult to debug in larger applications.

The Solution: Immutability

A better approach is to create a new object for each response entry, leaving the original statusInfo array unchanged. We can achieve this using map and the spread operator (...):

const result = response.map(({ status, value }) => {
const currentStatus = statusInfo.find(info => info.status === status);
return currentStatus
? { ...currentStatus, text: value || currentStatus.text }
: null; // Handle unmatched statuses
}).filter(Boolean); // Remove null values if any
console.log(result);
console.log(statusInfo);

Why Immutability Matters

Immutability is a foundational principle in functional programming and modern JavaScript practices. It ensures:

  • Predictability: Objects and arrays retain their original state, reducing side effects.
  • Reusability: Data structures can be reused without worry about unexpected changes.
  • Debugging Ease: With fewer side effects, bugs are easier to trace and resolve.

Final Thoughts

Unintended mutations can cause significant issues in JavaScript, especially in applications with shared data. By adopting immutability practices, you not only write safer code but also align with modern best practices.

Whenever you’re manipulating objects or arrays, ask yourself: “Am I modifying the original data?” If the answer is yes, consider an alternative approach like spreading or mapping to create a new copy.

By understanding and avoiding mutation, you can build applications that are easier to maintain, debug, and scale.

I hope you found this article useful. I would love to hear your thoughts. 😇

Thanks for reading. 😊

Cheers! 😃

If you find this article useful, you can show your appreciation by clicking on the clap button. As the saying goes, ‘When we give cheerfully and accept gratefully, everyone is blessed’.

--

--

Ishwar Rimal
Ishwar Rimal

Written by Ishwar Rimal

Senior FrontEnd Engineer at Intuit. 8 years experience. I write articles on JavaScript, React, Web Optimisation, Startups, Work Life Balance, etc. ❤️ JavaScrip

No responses yet