Shallow and deep copy of JavaScript

Keywords: Javascript JSON Attribute

I. understanding

Shallow copy only copies the pointer to an object, not the object itself. The new and old objects still share the same block of memory. But deep copy will create another object that is exactly the same. The new object does not share memory with the original object, and the new object will not be changed to the original object.

Shallow copy and deep copy

  1. Shallow copy: when assigning a value, the basic data type is passed by value, and the object is passed by reference

    var a = 25;
    var b = a;
    b = 18;
    console.log(a);//25
    console.log(b);//18
    // b's modification does not affect a, because they are basic type data
    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = obj1;
    obj2.b = 100;
    console.log(obj1);
    // {A: 10, B: 100, C: 30} < -- B was changed to
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }
    // Obj 2 modifies the value of b, and obj 1's b will also be modified, because they are the same object, which is called shallow copy
  2. Deep copy:

    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
    obj2.b = 100;
    console.log(obj1);
    // {A: 10, B: 20, C: 30} < -- B has not been changed to
    console.log(obj2);
    // { a: 10, b: 100, c: 30 }

III. implementation mode

  1. Implementation of shallow copy
    (1) direct assignment is shallow copy. If the object is copied directly, the changes of the new object will also be modified to the old object.
    (2) Object.assign(target, ...sources)

    Object.assignyesES6New function for.Object.assign()Method can copy the enumerable properties of any multiple source objects to the target object, and then return to the target object. howeverObject.assign()Shallow copy is performed, and attribute value is copied. If the property value of the source object is a reference to the object, it only copies that reference value.

    var obj = { a: {a: "hello", b: 21} };
    var initalObj = Object.assign({}, obj);
    
    initalObj.a.a = "changed";
    console.log(obj.a.a); // "changed"

    (3) object expansion

    var obj = [{index: 1, msg: 'one'}, {index: 2, msg: 'two'}];
    var obj2 = [...obj];
    
    console.log(obj2); //[{index: 1, msg: 'one'}, {index: 2, msg: 'two'}]
    
    obj2.push({index: 3, msg: 'three'});
    console.log(obj2); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two'}, {index: 3, msg: 'three'}]
    console.log(obj); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two'}]
    
    obj2[1].msg = 'two again';
    console.log(obj2); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two again'}, {index: 3, msg: 'three'}]
    console.log(obj); // [{index: 1, msg: 'one'}, {index: 2, msg: 'two again'}]
  2. Implementation of deep copy
    (1) manual copy

    var obj1 = { a: 10, b: 20, c: 30 };
    var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };

    (2) convert to JSON and then switch back (only objects that can be converted to JSON format can be used in this way, like function, which can't be converted to JSON)

    var obj1 = { body: { a: 10 } };
    var obj2 = JSON.parse(JSON.stringify(obj1));
    obj2.body.a = 20;
    console.log(obj1);
    // {body: {A: 10}} < -- not changed to
    console.log(obj2);
    // { body: { a: 20 } }
    console.log(obj1 === obj2);
    // false
    console.log(obj1.body === obj2.body);
    // false

    (3) use var newObj = Object.create(oldObj) method

    function deepClone(initalObj, finalObj) {    
      var obj = finalObj || {};    
      for (var i in initalObj) {        
        var prop = initalObj[i];        // Avoid dead loops caused by cross referencing objects, such as 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;
    }
    
    var str = {};
    var obj = { a: {a: "hello", b: 21} };
    deepClone(obj, str);

Four, reference

[1]On shallow and deep copy of JavaScript

Posted by jawaidpk on Wed, 04 Dec 2019 22:45:26 -0800