[JavaScript] Practical Data Manipulation: Leveraging Immutability and Mutability for Robust Code

目次

Overview

Data types in JavaScript are broadly classified into two categories based on whether their values are Mutable (changeable) or Immutable (unchangeable). Failing to grasp these properties often leads to side effects where data is modified in unexpected locations. This article organizes the behavioral differences between primitive and object types to provide a foundation for safe data management.


Specifications (Characteristics)

CategoryCharacteristicTarget TypesDefinition
Primitive TypeImmutableNumber, String, Boolean, Null, undefined, SymbolOnce created, the value itself cannot be changed. Updating a variable requires “reassignment” with a completely new value.
Object TypeMutableObject, Array, FunctionInternal properties or elements can be modified directly while maintaining the same object structure and memory reference.

Basic Usage

When operating on primitive types like numbers or strings, you are always “generating a new value.” In contrast, object types like arrays or literal objects allow you to modify their internal state while pointing to the same memory area. Therefore, when multiple variables share a single object, you must be cautious of “side effects” where an operation on one variable affects another.


Full Code Implementation (HTML / JAVASCRIPT)

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Environmental Monitoring System</title>
</head>
<body>
    <div id="monitor-app">
        <h2>Environmental Monitoring Data Management</h2>
        <div id="log-display">
            <p>Current Threshold: <span id="threshold-val">--</span></p>
            <p>Latest Log: <span id="latest-log">--</span></p>
        </div>
        <hr>
        <button id="btn-update-primitive">Update Threshold (Reassignment)</button>
        <button id="btn-mutate-object">Manipulate Log Array (Mutative Update)</button>
    </div>
    <script type="module" src="main.js"></script>
</body>
</html>

JavaScript

/**
 * Monitoring System Management Script
 * Operator: mori
 */

// 1. Primitive Type (Immutable) Example
// Since the number itself cannot be changed, use 'let' to allow "reassignment"
let alertThreshold = 25;

// 2. Object Type (Mutable) Example
// Modifying array contents directly does not change the reference the variable points to (can use 'const')
const temperatureLogs = [22, 24, 23];

const thresholdElement = document.getElementById('threshold-val');
const logElement = document.getElementById('latest-log');

/** Updates the UI display */
const updateUI = () => {
  thresholdElement.textContent = `${alertThreshold}℃`;
  logElement.textContent = temperatureLogs.join(', ');
};

// Primitive Operation: Generating a new value and assigning it
document.getElementById('btn-update-primitive').addEventListener('click', () => {
  // The value 25 does not turn into 30; instead, a new value 30 is stored in the variable
  alertThreshold = 30;
  console.log('Reassigned threshold:', alertThreshold);
  updateUI();
});

// Object Operation: Modifying data at the existing memory reference (Mutable)
document.getElementById('btn-mutate-object').addEventListener('click', () => {
  // Directly overwriting the first element of the array (destructive operation)
  temperatureLogs[0] = 100;
  // Adding a new element
  temperatureLogs.push(26);
  
  console.log('Modified array internally:', temperatureLogs);
  updateUI();
});

// Initial Render
updateUI();

Customization Points

  • Use let and const appropriately. Use let for primitive types that require reassignment and const for object types to clarify that the reference itself should remain fixed.
  • When performing array operations, if you need to protect the original data, consider using non-destructive generation like the spread syntax [...logs, newValue] instead of push.

Important Considerations

  • Attempts to “modify” primitive types (e.g., trying to overwrite a specific character in a string) will fail; the original value remains even if no error is thrown.
  • Due to the mutable nature of objects, passing an array to a function and modifying it internally will change the data in the calling scope. This behavior, involving shared references, can become a source of unexpected bugs in large-scale development.
  • Remember that const only prevents “reassignment” to the variable; it does not prohibit “internal modifications” to the object’s properties.

Advanced Applications

The following example demonstrates the behavior when attempting to modify a string (immutable) and the correct way to update it.

/**
 * Username Formatting Logic
 * Operator: mori
 */
let userName = "mori";

// Strings are immutable, so index-based modification is impossible
userName[0] = "M"; 
console.log(userName); // Still "mori" (fails silently)

// Correct approach: Generate a new string and reassign it
userName = "M" + userName.slice(1);
console.log(userName); // "Mori"

Summary

The handling of data in JavaScript is governed by the inherent properties of immutability and mutability associated with each type. Primitive types such as numbers and strings never undergo internal changes; instead, they are always replaced with entirely new states. Conversely, arrays and objects can update their internal state while sharing the same physical entity in memory. While this allows for flexible operations, it also carries the risk of unintended data inconsistency. Developers must remain conscious of these characteristics and strategically choose between reassignment-based updates and internal property manipulation depending on the specific requirements of the application.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次