Table of Contents
1. Implementation of shallow copy
1.1 Method 1: Simple copy statement
1.2 Method 2: Object.assign()
2. Implementation of deep copy
2.1 Method 1: Use JSON.parse() method
2.2 Method 2: Recursive copy
2.3 Method 3: Use the Object.create() method
3. Reference: Implementation of jQuery.extend() method
Home Web Front-end JS Tutorial Deep copy of objects in JavaScript

Deep copy of objects in JavaScript

Feb 21, 2017 pm 12:00 PM
object deep copy



In JavaScript, it is common to copy objects. But a simple copy statement can only make a shallow copy of an object, that is, a reference is copied, not the object it refers to. More often, we want to make a deep copy of the object to prevent the original object from being unintentionally modified.

The difference between deep copy and shallow copy of an object is as follows:

  • Shallow copy: only copies the reference of the object, not the object itself;

  • Deep copy: Copy all objects referenced by the copied object.

1. Implementation of shallow copy

The implementation method of shallow copy is relatively simple, as long as a simple copy statement is used.

1.1 Method 1: Simple copy statement

/* ================ 浅拷贝 ================ */
function simpleClone(initalObj) {
    var obj = {};
    for ( var i in initalObj) {
        obj[i] = initalObj[i];
    }
    return obj;
}
Copy after login
/* ================ 客户端调用 ================ */
var obj = {
    a: "hello",
    b: {
        a: "world",
        b: 21
    },
    c: ["Bob", "Tom", "Jenny"],
    d: function() {
        alert("hello world");
    }
}
var cloneObj = simpleClone(obj); // 对象拷贝

console.log(cloneObj.b); // {a: "world", b: 21}
console.log(cloneObj.c); // ["Bob", "Tom", "Jenny"]
console.log(cloneObj.d); // function() { alert("hello world"); }

// 修改拷贝后的对象
cloneObj.b.a = "changed";
cloneObj.c = [1, 2, 3];
cloneObj.d = function() { alert("changed"); };

console.log(obj.b); // {a: "changed", b: 21} // // 原对象所引用的对象被修改了

console.log(obj.c); // ["Bob", "Tom", "Jenny"] // 原对象所引用的对象未被修改
console.log(obj.d); // function() { alert("hello world"); } // 原对象所引用的函数未被修改
Copy after login

1.2 Method 2: Object.assign()

Object.assign() method can assign any number of source objects Copies its own enumerable properties to the target object, and then returns the target object. However, Object.assign() performs a shallow copy, copying references to the properties of the object, not the object itself.

var obj = { a: {a: "hello", b: 21} };

var initalObj = Object.assign({}, obj);

initalObj.a.a = "changed";

console.log(obj.a.a); // "changed"
Copy after login

2. Implementation of deep copy

There are many ways to implement deep copy, including the simplest JSON.parse() method, the commonly used recursive copy method, and the Object in ES5 .create() method.

2.1 Method 1: Use JSON.parse() method

There are many ways to implement deep copy. For example, the simplest way is to use JSON.parse():

/* ================ 深拷贝 ================ */
function deepClone(initalObj) {
    var obj = {};
    try {
        obj = JSON.parse(JSON.stringify(initalObj));
    }
    return obj;
}
Copy after login
/* ================ 客户端调用 ================ */
var obj = {
    a: {
        a: "world",
        b: 21
    }
}
var cloneObj = deepClone(obj);
cloneObj.a.a = "changed";

console.log(obj.a.a); // "world"
Copy after login

This method is simple and easy to use.

But this method also has many disadvantages, for example, it will discard the object's constructor. That is to say, after deep copying, no matter what the original constructor of the object is, it will become Object after deep copying.

The only objects that this method can correctly handle are Number, String, Boolean, Array, and flat objects, that is, those data structures that can be directly represented by json. RegExp objects cannot be deep copied in this way.

2.2 Method 2: Recursive copy

The code is as follows:

/* ================ 深拷贝 ================ */
function deepClone(initalObj, finalObj) {
    var obj = finalObj || {};
    for (var i in initalObj) {
        if (typeof initalObj[i] === 'object') {
            obj[i] = (initalObj[i].constructor === Array) ? [] : {};
            arguments.callee(initalObj[i], obj[i]);
        } else {
            obj[i] = initalObj[i];
        }
    }
    return obj;
}
Copy after login

The above code can indeed achieve deep copy. But when encountering two objects that reference each other, an infinite loop will occur.

In order to avoid an infinite loop caused by objects referencing each other, you should determine whether objects refer to each other during traversal, and if so, exit the loop.

The improved version of the code is as follows:

/* ================ 深拷贝 ================ */
function deepClone(initalObj, finalObj) {
    var obj = finalObj || {};
    for (var i in initalObj) {
        var prop = initalObj[i];

        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
        if(prop === obj) {
            continue;
        }

        if (typeof prop === 'object') {
            obj[i] = (prop.constructor === Array) ? [] : {};
            arguments.callee(prop, obj[i]);
        } else {
            obj[i] = prop;
        }
    }
    return obj;
}
Copy after login

2.3 Method 3: Use the Object.create() method

Use var newObj = Object.create(oldObj) directly to achieve deep copy effect.

/* ================ 深拷贝 ================ */
function deepClone(initalObj, finalObj) {
    var obj = finalObj || {};
    for (var i in initalObj) {
        var prop = initalObj[i];

        // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况
        if(prop === obj) {
            continue;
        }

        if (typeof prop === 'object') {
            obj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
        } else {
            obj[i] = prop;
        }
    }
    return obj;
}
Copy after login

3. Reference: Implementation of jQuery.extend() method

jQuery.extend() of jQuery.js also implements deep copy of the object. The official code is posted below for reference.

Official link address: http://www.php.cn/.

jQuery.extend = jQuery.fn.extend = function() {
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[ 0 ] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if ( typeof target === "boolean" ) {
        deep = target;

        // Skip the boolean and the target
        target = arguments[ i ] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
        target = {};
    }

    // Extend jQuery itself if only one argument is passed
    if ( i === length ) {
        target = this;
        i--;
    }

    for ( ; i < length; i++ ) {

        // Only deal with non-null/undefined values
        if ( ( options = arguments[ i ] ) != null ) {

            // Extend the base object
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];

                // Prevent never-ending loop
                if ( target === copy ) {
                    continue;
                }

                // Recurse if we&#39;re merging plain objects or arrays
                if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                    ( copyIsArray = jQuery.isArray( copy ) ) ) ) {

                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && jQuery.isArray( src ) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject( src ) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don&#39;t bring in undefined values
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};
Copy after login


The above is the content of deep copying of objects in JavaScript. For more related content, please pay attention to the PHP Chinese website (www.php. cn)!






#

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Convert an array or object to a JSON string using PHP's json_encode() function Convert an array or object to a JSON string using PHP's json_encode() function Nov 03, 2023 pm 03:30 PM

JSON (JavaScriptObjectNotation) is a lightweight data exchange format that has become a common format for data exchange between web applications. PHP's json_encode() function can convert an array or object into a JSON string. This article will introduce how to use PHP's json_encode() function, including syntax, parameters, return values, and specific examples. Syntax The syntax of the json_encode() function is as follows: st

How to convert MySQL query result array to object? How to convert MySQL query result array to object? Apr 29, 2024 pm 01:09 PM

Here's how to convert a MySQL query result array into an object: Create an empty object array. Loop through the resulting array and create a new object for each row. Use a foreach loop to assign the key-value pairs of each row to the corresponding properties of the new object. Adds a new object to the object array. Close the database connection.

Use Python's __contains__() function to define the containment operation of an object Use Python's __contains__() function to define the containment operation of an object Aug 22, 2023 pm 04:23 PM

Use Python's __contains__() function to define the containment operation of an object. Python is a concise and powerful programming language that provides many powerful features to handle various types of data. One of them is to implement the containment operation of objects by defining the __contains__() function. This article will introduce how to use the __contains__() function to define the containment operation of an object, and give some sample code. The __contains__() function is Pytho

Source code exploration: How are objects called in Python? Source code exploration: How are objects called in Python? May 11, 2023 am 11:46 AM

Wedge We know that objects are created in two main ways, one is through Python/CAPI, and the other is by calling a type object. For instance objects of built-in types, both methods are supported. For example, lists can be created through [] or list(). The former is Python/CAPI and the latter is a calling type object. But for instance objects of custom classes, we can only create them by calling type objects. If an object can be called, then the object is callable, otherwise it is not callable. Determining whether an object is callable depends on whether a method is defined in its corresponding type object. like

What is the difference between shallow copy and deep copy in Java? What is the difference between shallow copy and deep copy in Java? Apr 11, 2024 pm 12:33 PM

The difference between shallow copy and deep copy: Shallow copy: Create an object that references the same data, and changes to the copy will also affect the original object. Deep copy: Create an object that contains a copy of the original object's data. Changing the copy will not affect the original object.

What is the difference between arrays and objects in PHP? What is the difference between arrays and objects in PHP? Apr 29, 2024 pm 02:39 PM

In PHP, an array is an ordered sequence, and elements are accessed by index; an object is an entity with properties and methods, created through the new keyword. Array access is via index, object access is via properties/methods. Array values ​​are passed and object references are passed.

Detailed explanation of 5 loop traversal methods of Javascript objects Detailed explanation of 5 loop traversal methods of Javascript objects Aug 04, 2022 pm 05:28 PM

How to loop through Javascript objects? The following article will introduce five JS object traversal methods in detail, and briefly compare these five methods. I hope it will be helpful to you!

Use Python's __le__() function to define a less than or equal comparison of two objects Use Python's __le__() function to define a less than or equal comparison of two objects Aug 21, 2023 pm 09:29 PM

Title: Using Python's __le__() function to define a less than or equal comparison of two objects In Python, we can define comparison operations between objects by using special methods. One of them is the __le__() function, which is used to define less than or equal comparisons. The __le__() function is a magic method in Python and is a special function used to implement the "less than or equal" operation. When we compare two objects using the less than or equal operator (&lt;=), Python

See all articles