The relationship between deep and shallow copies and assignments

Why research

var person1 = {
    name: "Zhang".age: "45".children: {
        name: "Zhang heart".age: '12',},arr: [1[2.3].4.5]}Copy the code

Try changing the value

// Make a copy
var person2 = person1

// Change the copied value
person2.name = 'bill'
person2.children.name = 'Li Sihai';
person2.arr[1] [1] = 'm'

// Print it
console.log(person1)
/ / {
//    name: "李四", 
// age: "45",
// children: {
// name: "Li Sihai"
// age: "12"},
/ / arr: [1, 2, 'm'], 4, 5)
/ /}
/ /}
Copy the code

You can see that changing person2 directly changes person1

This is obviously not what we want. Is this a bug? Person2 and person1 are both assigned to the same heap. Changing the value of person2 changes the heap as well. This also causes the value of person1 to change

Shallow copy

Create a new memory address, iterate over all the keys of person1, copy the corresponding key-values one by one, so that the two memory addresses belong to each other, and the two heaps do not affect each other

// Encapsulate the copy method
function shallowClone(obj){
  const shallowCloneObj = {}
  for(let key in obj){
    shallowCloneObj[key] = obj[key]
  }
  return shallowCloneObj
}
// Make a shallow copy
person3 = shallowClone(person1)
person3.name = "Fifty"
person3.children.name = "Wang hao"
person3.arr[1] = 'w'
console.log(person3)
/ / {name: "detective", the age: "45", the children: {name: "wang hao", the age: "12"}, arr: (4) [1, "w", 4, 5]
console.log(person1)
/ / {name: "zhang", the age: "45", the children: {name: "wang hao", the age: "12"}, arr: (4) [1, "w", 4, 5]

Copy the code

It is obvious that the base type values in person1 are not affected after a layer of conversion, but the reference type values are still changed, mainly because the shallow copy only copies one layer, not the entire copy

Such incomplete copying is called shallow copying

Deep copy

Deep copy is a recursive process based on shallow copy until all child elements have been copied

// Define the deep-copy method
function deepClone(obj){
    if (obj === null) return obj;
     // Resolve date and re copy issues
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof RegExp) return new RegExp(obj);
    if (typeofobj ! = ="object") return obj; // Stop recursion
    var deepCloneObj= {}
    for(let key in obj){
        // Recursion is required only if the child element is object. Note that the null typeof is also object
        if(typeof obj[key] == 'object' && typeofobj[key] ! =null) {// We need to recurse so that the reference type also changes the memory address and assigns the content
            deepCloneObj[key] = deepClone(obj[key])
        }else{
         deepCloneObj[key] = obj[key]
        }
    }
    return deepCloneObj;
}
// Verify
person3 = deepClone(person1)
person3.name = "Fifty"
person3.children.name = "Wang hao"
person3.arr[1] = 'w'
console.log(person3)
/ / {name: "detective", the age: "45", the children: {name: "wang hao", the age: "12"}, arr: (4) [1, "w", 4, 5]
console.log(person1)
/ / {name: "zhang", the age: "45", the children: {name: "picture heart", the age: "12"}, arr: [[2, 3] 1, 4, 5]
Copy the code

Obviously, the child element is still a reference type, and the recursive method can make the elements before and after the copy do not affect each other, which is called deep copy

The simplest deep copy

The conversion is done using JSON, which gives the new value a new memory address, but JSON cannot parse special formats including function,Date, and RegExp

function deepClone(obj){
    let  newObj = JSON.stringfy(obj),
            cloneObj = JSON.parse(newObj);
    return cloneObj;
}
Copy the code