Abstract: The reason why there is the problem of shallow copy is essentially due to the different processing of JS for basic type and reference type.

This article is shared from Huawei cloud community “JS depth of replication, a look to understand”, the author: Xin 2020.

Shallow copy means

A shallow copy is a copy of only references to data stored in the stack; no copy references point to the contents of the heap. A shallow copy of multiple data, which copies multiple references that collectively point to the same content in the heap. When a shallow copy of the data is modified, that is, what the reference in the heap points to is changed, then other data pointed there by reference is changed as well.

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = obj;
objA.a = 'a';

console.log(obj.a);  // 'a'
console.log(objA.a);  // 'a'
Copy the code

Deep copy means deep copy

Deep copy refers to copying along with the contents of the heap to generate a new object. Multiple deep copies will be multiple different objects, with different references, pointing to different heap contents.

The reason for using deep copy

In normal development, sometimes there will be data transmission and reception, when the data is transmitted, it is inevitable to process and transform the data, in order not to destroy the original data structure, then you can use deep copy of the data, and then process the new data generated. Deep copy also prevents messy references after modifying multiple references, reducing the chance of bugs.

There are several ways to achieve deep replication

Implementation method 1: SERIalization and deserialization of JSON

let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = JSON.parse(JSON.stringify(obj)); Obja. a = 'a'; console.log(obj.a); // 1 console.log(objA.a); // 'a'Copy the code

Although serialization and deserialization of JSON can achieve deep copy, there are several disadvantages to note:

The date object is converted to a date date string

2. The prototype cannot be accessed

3, cannot copy undefined attribute

NAN and infinity are NULL

let d1 = new Date();
let obj = {
    d1,
    d2: undefined,
    d3:NaN
}
let objD = JSON.parse(JSON.stringify(obj));
console.log(obj) 
console.log(objD)
Copy the code

Object.assign()

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

let objA = Object.assign(obj);
objA.a = 'a';

console.log(obj.a);  // 1
console.log(objA.a);  // 'a'
Copy the code

Although object.assign () can be used for deep copying, it is only shallow copying for deeper Object references.

let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = Object.assign(obj); objA.c.c1 = 'c1'; // object.assign () is just a deep copy layer. console.log(obj.c.c1); // 'c1' console.log(objA.c.c1); // 'c1'Copy the code

Implementation method three: extend the operator

let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = {... obj};; objA.a = 'a'; console.log(obj.a); // 1 console.log(objA.a); // 'a'Copy the code

Although the extension operator “…” Deep copying is possible, but only shallow copying is possible for deeper object references.

let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = {... obj}; objA.c.c1 = 'c1'; // Extend operator "..." As with object.assign (), only one deep copy, not multiple deep copies. console.log(obj.c.c1); // 'c1' console.log(objA.c.c1); // 'c1'Copy the code

Implementation method four: use recursion

To achieve deep replication, with multiple layers of deep replication, you can use recursive circular replication.

let obj = {
    a:1,
    b:2,
    c:{
        c1:10,
        c2:20
    }
}

const ReCopy = function (paramter) {
        let target = null;
        let isObject = paramter.constructor === Object;
        let isArray = paramter.constructor === Array;
        if (isObject || isArray) {
            target = Array.isArray(paramter) ? [] : {};
            for (let i in paramter) {
                target[i] = ReCopy(paramter[i]);
            }
        } else {
            target = paramter;
        }
        return target;
    }

let objA = ReCopy(obj);
objA.c.c1 = 'c1';

console.log(obj.c.c1);  // 10
console.log(objA.c.c1);  // 'c1'
Copy the code

Ladash deep copy

Lodash deep copy is a more professional deep copy method.

  • Install lodash

Initialize, generate package.json file, and install using the following command.

npm i -S lodash
Copy the code
  • The introduction of lodash

    var _ = require(‘lodash’);

  • Using lodash

    let obj = { a:1, b:2, c:{ c1:10, c2:20 } }

    let objA = _.cloneDeep(obj); objA.c.c1 = ‘c1’;

    console.log(obj.c.c1); // 10 console.log(objA.c.c1); // ‘c1’

Click to follow, the first time to learn about Huawei cloud fresh technology ~