So before we look at deep copy, what is deep copy?

In JS, data types are divided into basic data types and reference data types. For basic data types, its value is stored directly in stack memory, while for reference types, it only stores a reference in stack memory, while the real data is stored in heap memory

When we manipulate data, two things happen

Basic data types

var a = 3; var b = a; b = 5; console.log(a); // 3 console.log(b); / / 5Copy the code

What you can see is that for primitive types, we assign the value of a primitive type to variable A, and then we assign the value of A to variable B; And then we modify b; You can see that b is modified, but a is not. Both variables use independent data.

2. Reference data types

var obj1 = { a: 1, b: 2, c: 3 } var obj2 = obj1; obj2.a = 5; console.log(obj1.a); // 5 console.log(obj2.a); / / 5Copy the code

What you can see is that both objects have been modified. The object is the value of the reference type. For the reference type, when we assign obj1 to obj2, we’re just assigning obj1’s stack reference to obj2, and both objects are pointing to the same data in the heap. So when we modify any value, we are modifying the data in the heap, not the reference, so as long as we modify, the value of the referenced object is automatically changed

In fact, the above example is a simple shallow copy, and the corresponding shallow copy, is the topic of our article, deep copy!

Shallow copy

For shallow copies, only the reference to the object is copied, but the value of the object is not deeply copied. Multiple objects point to the same object in heap memory, and any modification causes all objects to change their value because they share a single data

Deep copy

In a real project, we definitely can’t have every object value pointing to the same heap memory, which is not easy for us to do operations, so naturally born deep copy deep copy function on the reference type! For example, Object and Array deep copy does not copy the references of the reference type, but copies all the values of the reference type to form a new reference type. In this way, the problem of reference confusion does not occur, so that we can use the same data for many times without worrying about data conflicts

Third, the implementation of deep copy

  1. Take a look at the beggar’s deep copy first! JSON. Stringify (), and JSON. The parse ()
var obj1 = { a: 1, b: 2, c: 3 } var objString = JSON.stringify(obj1); var obj2 = JSON.parse(objString); obj2.a = 5; console.log(obj1.a); // 1 console.log(obj2.a); / / 5Copy the code

You can see that there is no reference problem, and changing obj2’s data does not affect obj1 at all. But why is it beggar’s version? That’s because with json.stringify () and json.parse () it can’t copy undefined, function, RegExp, etc

  1. Then look at the second method object.assign (target, source)
var obj1 = { a: 1, b: 2, c: 3 } var obj2 = Object.assign({}, obj1); obj2.b = 5; console.log(obj1.b); // 2 console.log(obj2.b); / / 5Copy the code

The second approach doesn’t seem to have any problems either, but this is one layer of objects, if there are multiple layers of nesting

 var obj1 = {
    a: 1,
    b: 2,
    c: ['a','b','c']
}
var obj2 = Object.assign({}, obj1);
obj2.c[1] = 5;
console.log(obj1.c); // ["a", 5, "c"]
console.log(obj2.c); // ["a", 5, "c"]
Copy the code

As you can see, there is no problem for a layer object, but there is still a problem if the object attributes correspond to other reference types and only the reference is copied

  1. The third way is recursive copy
Function deepClone(target) {// define a variable let result; // If (typeof target === 'object') {if (array.isarray (target)) {result = []; // If (array.isarray (target)) {result = []; Result.push (deepClone(target[I]))} // Determine if the current value is null; Else if(target===null) {result =null; } else if(target.constructor===RegExp){result = target; }else {result = {}; for (let i in target) { result[i] = deepClone(target[i]); } else {result = target;} else {result = target; } // return result; }Copy the code

You can see the effect
    let obj1 = {
        a: {
            c: /a/,
            d: undefined,
            b: null
        },
        b: function () {
            console.log(this.a)
        },
        c: [
            {
                a: 'c',
                b: /b/,
                c: undefined
            },
            'a',
            3
        ]
    }
    let obj2 = deepClone(obj1);
        console.log(obj2);
Copy the code

! [](//upload-images.jianshu.io/upload_images/18087456-4df102c214490d01.png? imageMogr2/auto-orient/strip|imageView2/2/w/664/format/webp)

Deep copy

You can see that the final copy result is null, undefinde, function, RegExp and other special values are also copied successfully, and there is no problem in modifying the values inside. There are still many problems that have not been solved, but to provide you with an idea