A Comprehensive Understanding of Deep and Shallow Copies

Keywords: Javascript JSON Attribute

About Deep Copy and Shallow Copy

From the point of view of principle:

  • Shallow copy: Copy one layer, and copy references at the object level
  • Deep Copy: Copy multiple layers, with attributes at each level being copied

From the phenomenal point of view:
A copied B, and B was modified.

  • A varies with B - > shallow copy
  • B unchanged - > deep copy

Deep copy of s complex object type data for
For example, a single-layer copy of a direct assignment, such as b=a, b is not affected by a, but it is not considered as a deep copy.
Phenomenon is only a reference for easy understanding. The real criterion of judgment should be seen in principle.

Data types are divided into:

  1. Basic data types (7): namevalue is stored in stack memory
  2. Reference data type: name - > stack memory, value - > heap memory, stack memory will provide a reference address to the value of heap memory

When b=a is copied, b copies the quoted address of a, not the value in the heap, so this creates a shallow copy of b that changes when a changes.

Method of realizing shallow copy:
Direct Reproduction

//Basic data types
var arr = [1, 2, 3, '4'];

var arr2 = arr;
arr2[1] = "test"; 
console.log(arr); // [1, "test", 3, "4"]
console.log(arr2); // [1, "test", 3, "4"]
//Changing the attribute value of one of the objects changes both objects 
//Both obj and obj2 variables point to the same pointer. When assigning a value, they just copy the pointer address and point to the same reference. When we change the value of one variable, the value of the other variable will change accordingly.


----------


//Object level
function Clone(obj1){
    var obj2 ={};
    for(var i in obj1)
    {
        obj2[i]=obj1[i];
    }
    return obj2;
}

Shallow copy only copies one layer, except that the object is a copy reference type, the other is to pass the value directly, with its own memory space.

Object.assign() method in ES6
This method can copy enumerable attributes of any number of source objects to the object, and then return to the target object.

Object. assign (target object, any number of source objects)
var obj1 = {
    a: "hello",
    b: {
        a: "hello",
        b: 21}
};
 
var cloneObj1= Object.assign({}, obj1);
cloneObj1.a = "changed";
cloneObj1.b.a = "changed";
console.log(obj1.a);  //hello
console.log(obj.b.a); // "changed"

If the object has only one layer, this function can be used as a method of deep copy.

var obj2 = { a: 10, b: 20, c: 30 };
var cloneObj2 = Object.assign({}, obj2);
cloneObj2.b = 100;
console.log(obj2);
// {a: 10, b: 20, c: 30} < - No change, deep copy
console.log(cloneObj2);
// { a: 10, b: 100, c: 30 }

If you want to achieve deep copy, you need to open up a memory in the heap to store the value of b.

Method 1. Manual replication
Responsibility for assigning attributes of object A item to attributes of another object one by one

var ob1 = {a:1,b:2,c:3};
var ob2 = {a:ob1.a,b:ob1.b,c:ob1.c};
ob1.a = 0;
ob2.b = 0;
console.log(ob1);//023
console.log(ob2);//103

This is cumbersome and cannot be counted as a deep copy in essence. When ob1 nests object c, ob1 and ob2 will share c, and when c's attributes are changed, ob1 and ob2 will change

Method 2. Convert objects to strings by JSON method and back
Real deep copy can be achieved, but only for objects that can be converted to JSON format. function cannot be converted to JSON, so it cannot be used.
This method discards the constructor of the object

var ob1 ={c:{a:1,b:2}};
var ob2 =JSON.parse(JSON.stringfy(ob1));
//JSON.stringify is used to convert objects into strings, and JSON.parse is used to convert strings into new objects.

Method 3. Recursive copy

function deepClone(obj1,obj2){
    var obj = obj2|| {};//If obj exists, it is defined as obj2, otherwise an empty object is created
        for(var i in obj1){//Traversing the original object
        if(typeof obj1[i] === 'object'){//If the current element is an object
        
            obj[i] = Array.isArray(obj1[i]) ?[]:{};//Judging whether it is an array or an object 
            deepClone(obj1[i],obj[i]);//Use recursion to traverse layer by layer until the last layer
        }
        else{

            obj[i] = obj1[i];//assignment
        }
        
    }
    return obj;

}

var str = {};
var obj = { a: {a: "Leemo", b: 19980228} };
deepClone(obj, str);
console.log(str.a);

Method 4. Use Object.create() method

var Obj2 = object.create(Obj1);
//Implementing Obj2 Deep Copy Obj1

Reference documents:
Document 1
Document 2

Posted by csn on Wed, 01 May 2019 09:00:38 -0700