There are two concepts that come up a lot in job coding and in interviews: deep copy and shallow copy. But today’s focus is on deep copy.

I’m going to talk a little bit about what is deep copy, shallow copy?

Shallow copy is a direct copy of all the attributes and property values of one Object to another Object. As a result, the Object attributes of the new Object and the old Object point to the same memory. That is, the Object attributes of the new Object and the old Object point to the same memory. So modifying the new object or modifying the original object will interfere with each other.

A deep copy is a complete copy of an Object into a new Object. Modifying the properties or value of the original object does not affect the new object. The original object and the new object are completely independent and do not affect each other.

And then just to add a little bit, just assign

Direct assignment, simple assignment if it’s for a primitive type. If the Object is of type Object, the address of the original Object is assigned to the new Object. In other words, the original Object and the new Object are identical. Once the properties or values of the properties are modified, the original Object and the new Object will affect each other.

Today’s focus is on deep copy, shallow copy is nothing to talk about. Talk is cheap, show me the code!

Shallow copy code:

function shallowCopy(obj) { if (! (obj instanceof Object)) { return obj; } let newObj = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = obj[key]; } } return newObj; }Copy the code

Let’s focus on deep copy

The first is to convert an Object to a JSON string using json.stringify, and then convert the JSON string to an Object using json.parse. Let’s test it out:

let obj1 = { "name": "Umbrella", "sex": "man", "brothers": { "Umbrella001": 22, "Umbrella002": 23 } }; let obj2 = obj1; // let obj22 = shallowCopy(obj1); Obj2. name = "Umbrella1024"; console.log(obj1); console.log(obj22); let obj3 = JSON.parse(JSON.stringify(obj1)); console.log(obj3); obj1.sex = "boy"; console.log(obj3); obj1.brothers['Umbrella001'] = 99; console.log(obj22);Copy the code

Below is a screenshot of the run

1. After a direct assignment, if you modify any property or property value, the source object and the new object will interact. If you change obj2, obj1 will change accordingly. 2. Shallow copy. If the property value is changed to Object, the source Object and the new Object will affect each other. You can observe changes to obj22 and obj1. 3. Looking at obj3 and obj1, we can see that deep copy is possible with json.stringify and json.parse.

Let’s add more properties to the object, like a function.

let obj4 = { "name": "Umbrella", "sex": "man", "introduce": function () { console.log("My name is " + this.name); }}; obj4.introduce(); let obj5 = JSON.parse(JSON.stringify(obj4)); console.log(obj5); obj5.introduce();Copy the code

Run screenshot:

As you can see, only the non-function attributes of the object can be copied out in this way. So deep copy via json. parse and json.stringify is not perfect.

So I share my own deep copy of an object method, this is my personal more commonly used scheme.

function deepCopy(obj) { if (obj instanceof Object) { let newObj = {}; if (Array.isArray(obj)) { let arr = []; obj.forEach(item => { arr.push(deepCopy(item)); }) return arr; } else { for (let key in obj) { let value = obj[key]; if (typeof value == 'function') { newObj[key] = value.bind(newObj); } else if (typeof value == 'object') { if (Array.isArray(value)) { newObj[key] = []; value.forEach(item => { newObj[key].push(deepCopy(item)); }) } else { newObj[key] = deepCopy(value); } } else { newObj[key] = value; } } } return newObj; } else { return obj; }}Copy the code

As you can see, in this method I wrote, I did something with the property value function.

Let’s test the deepCopy to see if it works.

let obj88 = {
    "name": "obj88"."sex": "man"."introduce": function () {
        console.log("My name is " + this.name); }}let obj8 = {
    "name": "Umbrella"."sex": "man"."introduce": function () {
        console.log("My name is " + this.name);
    },
    "brothers": [obj88]
};

console.log(obj8);

let obj9 = deepCopy(obj8);              / / copy
obj9.name = "Flex";

console.log(obj8);
console.log(obj9);

obj88.name = "obj88 Plus";
obj9.introduce();
obj9.brothers[0].introduce();
Copy the code

Running results:

As you can see, our deepCopy function is capable of deep copying, and is also compatible with the processing of property values of type function.

If have wrong leak, welcome big guy to clap brick ~