Deep Copy Techniques for JavaScript Objects: From Reference Passing to Independent Copies

Nov 28, 2025 · Programming · 10 views · 7.8

Keywords: JavaScript | Deep Copy | Object Cloning | JSON | Reference Passing

Abstract: This article provides an in-depth exploration of JavaScript's object reference passing mechanism and its associated challenges. It thoroughly analyzes the principles and limitations of using JSON.parse(JSON.stringify()) for deep copying, compares shallow versus deep copy differences, and references Apex language cloning implementations to comprehensively explain best practices for creating independent object copies across various scenarios. The article includes complete code examples and performance analysis to help developers fully understand and master core JavaScript object cloning techniques.

Analysis of JavaScript Object Passing Mechanism

In JavaScript, objects are passed by reference, meaning that when we assign an object to another variable, we are actually sharing the same memory address. This mechanism can be clearly demonstrated through the following code example:

var json_original = {one:'one', two:'two'}
var json_new = json_original;

console.log(json_original); // Output: {one: 'one', two: 'two'}
console.log(json_new); // Output: {one: 'one', two: 'two'}

json_original.one = 'two';
json_original.two = 'one';

console.log(json_original); // Output: {one: 'two', two: 'one'}
console.log(json_new); // Output: {one: 'two', two: 'one'}

From the output results, we can see that modifying properties of the original object json_original causes corresponding properties in the new variable json_new to change as well, confirming that both reference the same object instance.

Basic Concepts and Implementation Methods of Deep Copy

To create independent copies of objects and avoid side effects from reference sharing, we need to employ deep copy techniques. Deep copying recursively duplicates all levels of an object, ensuring the new object is completely independent from the original in memory.

For simple JSON objects, the most commonly used deep copy method utilizes JSON serialization and deserialization:

var json_original = {one:'one', two:'two'};
var json_new = JSON.parse(JSON.stringify(json_original));

json_original.one = 'modified';
console.log(json_original.one); // Output: 'modified'
console.log(json_new.one); // Output: 'one'

This method converts the object to a JSON string using JSON.stringify(), then parses it back into a new object using JSON.parse(), thereby achieving complete deep copying.

Principles and Limitations of JSON Deep Copy Method

The effectiveness of the JSON.parse(JSON.stringify()) method is based on the characteristics of the JSON data format. JSON only supports basic data types (strings, numbers, booleans, null) and two structural types (objects and arrays), so during serialization, certain JavaScript-specific data types are ignored or converted:

The following code demonstrates these limitations:

var obj = {
    func: function() { return 'hello'; },
    undef: undefined,
    date: new Date(),
    regex: /test/g
};

var cloned = JSON.parse(JSON.stringify(obj));
console.log(cloned.func); // Output: undefined
console.log(cloned.undef); // Output: undefined (missing in object)
console.log(cloned.date); // Output: date as string
console.log(cloned.regex); // Output: {}

Comparative Analysis of Other Deep Copy Methods

Beyond the JSON method, other deep copy implementations exist, each with distinct characteristics:

jQuery's Deep Copy Implementation

If jQuery library is used in the project, deep copying can be achieved using the jQuery.extend() method:

// Shallow copy
var shallowCopy = $.extend({}, originalObject);

// Deep copy
var deepCopy = $.extend(true, {}, originalObject);

jQuery's implementation can handle more JavaScript-specific data types but depends on external library inclusion.

Shallow Copy Characteristics of ES6 Spread Operator

ES6 introduced the spread operator, providing a concise way for shallow copying:

var shallowCopy = { ...oldObject };
var shallowCopyWithExtra = { ...oldObject, extraProp: 'value' };

It's important to note that this remains shallow copying, and nested objects still share references.

Deep Copy Implementation Philosophy from Apex Language Perspective

Referencing object cloning implementations in Apex language provides insights into general deep copy design patterns. In Apex, deep copying is achieved through custom clone methods:

public class CustomObject {
    public Integer primitiveValue = 0;
    public List<String> stringList = new List<String>{'a', 'b'};
    
    public CustomObject clone(Boolean deepClone) {
        CustomObject cloned = this.clone();
        if (deepClone) {
            cloned.stringList = stringList.clone();
        }
        return cloned;
    }
}

The core idea of this implementation is: directly copy values for primitive type members, and recursively call clone methods for complex type members. This pattern can be adapted to JavaScript for implementing more universal deep copy functions.

Performance Considerations and Best Practice Recommendations

When selecting deep copy methods, comprehensive consideration of performance, compatibility, and functional requirements is essential:

  1. Simple JSON Objects: Prefer JSON.parse(JSON.stringify()) for better performance and simplicity
  2. Complex Object Structures: Consider using specialized deep copy libraries or custom recursive functions
  3. Modern JavaScript Environments: Utilize structuredClone() API (limited browser support)
  4. Performance-Sensitive Scenarios: Avoid using deep copying in loops or high-frequency operations

Below is an example implementation of a universal deep copy function:

function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj;
    }
    
    if (obj instanceof Date) {
        return new Date(obj.getTime());
    }
    
    if (obj instanceof Array) {
        return obj.map(item => deepClone(item));
    }
    
    if (obj instanceof Object) {
        const cloned = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                cloned[key] = deepClone(obj[key]);
            }
        }
        return cloned;
    }
}

Practical Application Scenarios and Considerations

Deep copy technology is particularly important in the following scenarios:

When using deep copying, attention must be paid to memory usage and performance overhead, especially for large objects or deeply nested structures. In some cases, immutable data structure libraries can be considered for performance optimization.

By deeply understanding JavaScript's object reference mechanism and the characteristics of various deep copy methods, developers can select the most appropriate implementation based on specific requirements, ensuring code reliability and performance optimization.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.