Does copying in JavaScript change the original data? Experimenting with structuredClone and shallow copy

プログラミング・Web開発カテゴリを表すパンダのイラスト Programming / Web Development

About this article
This article is generated using an automated generation workflow utilizing generative AI. Based on official MDN documentation, we created educational material comparing copying methods using dummy configuration data.

Verification Status: 📘 Official MDN specification verified. 10 conditions passed for equivalent logic on Linux Node.js 22.16.0. Re-tests for GitHub-saved version, actual browsers, GitHub Pages, and WordPress rendering are unverified.

"I just copied the settings and edited them, but the original settings changed too." This strange phenomenon occurs when handling objects in JavaScript. The cause is:the difference between copying only the outer layer and copying nested data as well. This time, using dummy settings, we compare the results at the click of a button.

Try it first: Does the original setting change?

ItemConditions for this test
TargetstructuredClone()Supported browsers, Node.js 18 or later
Technologies usedJavaScript spread syntax, structuredClone, Date, Map
Cost & CommunicationStandard API only. No CDN, no API keys, no personal information, no external transmission
Actual measurements10 pure logic tests passed on Linux Node.js 22.16.0. Browser rendering unverified

Daily Code: Full code of fixed commit and README

We have not verified the reachability or actual functionality of the GitHub Pages public URL this time.The reliable way to check the sourceis to retrieve web/structured-clone-lab/ from the pinned commit above. The design is to run python3 -m http.server 8000 at the repository root and open http://127.0.0.1:8000/web/structured-clone-lab/. Stop with Ctrl+C. Actual browser behavior is unverified.

There are three operations.

  1. Click "Compare Again" to check the original data values.

  2. Observe that "Original data after shallow copy modification" becomes red.

  3. Compare how "Original data after deep copy modification" remains red, while only the copy side becomes green.

Note: The original data is already red due to the initial shallow copy modification. A deep copy does not revert this. We verify that modifying the deep copy does not further affect the original data.

Why the original data changes

In the next example, {...original} creates the outer object. However, settings points to the same nested object.

const original = {settings: {theme: "blue"}};
const shallow = {...original};
shallow.settings.theme = "red";
console.log(original.settings.theme); // "red"

Meanwhile,structuredClone() deeply clones the corresponding values.

const original = {settings: {theme: "blue"}};
const deep = structuredClone(original);
deep.settings.theme = "green";
console.log(original.settings.theme); // "blue"

These two code snippets are independent examples. The comparison button in the tutorial applies modifications to the same source data using a shallow copy, and then modifies the deep copy side.

flowchart TD
    A["元の架空設定"] --> B["浅いコピー {...original}"]
    A --> C["深いコピー structuredClone"]
    B --> D["入れ子の参照を共有"]
    C --> E["対応する入れ子も複製"]
    D --> F["変更が元データに反映"]
    E --> G["コピー側の変更は元に影響しない"]

Comparing Date and Map: Differences from JSON conversion

Frequently seen in legacy code, JSON.parse(JSON.stringify(value)) can also copy JSON-representable data into a new object. However, it does not preserve all original types.

DatastructuredCloneJSON serialization and deserialization
Nested plain objectDeeply clonedCloned within JSON-representable limits
DatePreserved as a DateConverted to an ISO format string
MapPreserved as a MapMaps in this tutorial become empty objects
Circular referenceSupportedJSON.stringify typically throws an error
FunctionsDataCloneErrorproperties may be omitted

That is,"being able to copy via JSON" and "being able to copy while preserving data types" are different. In this tutorial, Date and Map are used as fixed inputs, and the difference is displayed as text.

Try changing just one condition

First, change the nested value settings.theme. Next, copy the code and try changing only the non-nested team to "架空のB班". Even with a shallow copy, reassigning an outer string property does not affect the original data.

This comparison shows that shallow copies are not always dangerous, but rather thatit is important to understand and manage shared nested structures when using them. Immutability-based design, copying only necessary parts, and simplifying data structures are also valid options.

Troubleshooting when things do not work

SymptomPotential causeSolution
structuredClone is missingThe browser or runtime environment is outdated.Check compatibility. Node.js version 18 or later is assumed.
DataCloneError occurs.Unsupported values such as functions or DOM elements.Review the target to be duplicated.
The display does not change even when the button is pressed.JavaScript is disabled, or the file is not loaded.clone.js and app.jsCheck the path and developer tools for .
Date became a string.Duplicated via JSON.Consider whether the type needs to be preserved.
Slow with large data.Deep copies require time and memory.Reduce the duplication range.

structuredClone() is not a universal object cloning method. Functions and DOM elements cannot be cloned, and custom class prototypes or property descriptors are not preserved as-is. Pay attention to memory consumption when copying huge data. Although a transfer mechanism exists, it may render the original buffer unusable, so it is not covered in this introductory tutorial.

For professional use: Comparing before and after changes.

For example, when creating a "preview before saving" on a business system settings screen, if display changes are reflected in the original data, it can lead to bugs where changes cannot be reverted even if canceled. Identify the range where original values must be preserved and choose a copying method that matches the data type and capacity.

This tutorial uses only mock data. There is no need to enter actual customer data or confidential information into the demos. UI display, communication, saving, and WordPress display are not verified this time.

Official documentation

Organizing with diagrams: What to check before choosing a copy method

When a copied and modified value propagates back to the original data, the cause is not necessarily a JavaScript bug. Using the term "copied" without understanding object reference relationships makes it ambiguous whether only the outer container was duplicated or if the inner containers were also duplicated. A shallow copy creates a new outer object, but nested objects may retain the same references as the original.

flowchart TD
    A["コピーする値を調べる"] --> B{"入れ子の値があるか"}
    B -->|"ない"| C["浅いコピーでも足りるか検討"]
    B -->|"ある"| D{"入れ子も独立させる必要があるか"}
    D -->|"ない"| E["参照の共有を許可する設計か確認"]
    D -->|"ある"| F["structuredClone対応の型か確認"]
    F -->|"対応"| G["深いコピー後の変更を比較"]
    F -->|"非対応"| H["用途に合わせ別の明示的な複製処理"]
    G --> I["メモリー・性能・例外も確認"]

This diagram is not a universal decision algorithm applicable to all JavaScript values. For instance, functions, DOM elements, and instances of custom classes cannot necessarily be duplicated with the exact same functionality simply by using structuredClone. What is necessary is to first determine "what you want to change" and "what you want to leave intact in its original state."

Confirming that the same configuration is referenced

Just because the next two values look similar does not mean that two independent configurations are stored. With a shallow copy, even if the outer object is recreated, the nested properties may still point to the same reference. A small example using a fictitious color configuration allows you to compare whether inner references are shared.

const original = { settings: { theme: "blue" } };
const shallow = { ...original };
console.log(original === shallow); // false と予想
console.log(original.settings === shallow.settings); // true と予想

You can see that even though the outer objects are separate, the nested settings are the same object. Therefore, modifying shallow.settings.theme also changes original.settings.theme. Conversely, if you replace shallow.settings with a new object, it does not mean you have overwritten the original settings themselves. It is also incorrect to memorize that "because it is a shallow copy, changing anything will always propagate to the original."

What to compare before and after a deep copy

A deep copy is necessary not simply because nested structures exist, but when you want to keep the original configuration and the editing configuration independent. For example, suppose a business application has features like "preview changes" and "cancel." If the original configuration is modified directly in the preview, a bug occurs where canceling fails to revert to the previous value. Therefore, editable values must be made independent.

On the other hand, fully duplicating large data every time can cause issues with memory consumption and processing time. If the required scope is only partial, designing to explicitly update only that specific part becomes an alternative to consider. When choosing a copy method, consider the scope of changes and data volume, not just correctness.

Why copying via JSON is not a universal solution

While you may see the approach JSON.parse(JSON.stringify(value)), Date objects may become strings and fail to retain their original types. For values including Maps, functions, or circular references, some items cannot be represented or may not yield the expected results. Do not assume it is the same deep copy just because it can be written in two steps; verify what data types the copied data contains.

structuredClone also has values that cannot be cloned, which may result in a DataCloneError. The behavior of custom classes, getters, and property descriptors are not necessarily preserved completely as-is. To prevent the original data from being partially modified when an exception occurs, it is important to design copy and edit processes separately.

The Concept of "Reversible Changes" Useful in Business

In a mock application screen, settings might be modified and reviewed before saving, with the option to cancel if unsatisfied. In this scenario, it is natural to apply screen changes only to temporary data and reflect them in the actual data only after the save is confirmed. The copy method is one tool for this purpose, but how to update the destination state and how to detect conflicts when multiple users edit simultaneously are separate design challenges.

The highlight of this experiment is not just whether the values are the same, but tracking "where the same object is referenced." Observing the outer comparison, the nested comparison, and the original data after modification each time the code is changed makes it possible to explain why the values turned out differently than expected. Rather than simply memorizing a new API, this serves as training for considering where changes propagate.

Summary

There is more than one type of copy. First, observe in the order of shallow copy -> original nesting changes -> deep copy -> original remains unchanged. In practical work, verifying what you want to duplicate and which data types are included is the shortcut to safe design.

Document information

Article title
Does copying in JavaScript change the original data? Experimenting with structuredClone and shallow copy
Published
Updated
Source
https://papanda925.com/?p=18468&lang=en

License: Text and original figures for which this site holds the relevant rights are available under CC BY 4.0 , unless otherwise noted. This article may include content created or edited with generative AI. If code has a separate license notice or a linked GitHub repository license, that license takes precedence for the code. Quotations, third-party materials, images, and trademarks are excluded from this license. Usage policy

Copied title and URL