Some pits for deep copy implementation of JSON.parse(JSON.stringify(obj))

In js, how to use one line of code to achieve deep copy? It can be implemented: JSON.parse(JSON.stringify(obj)).
This line of code runs by using JSON.stringify to serialize the js object (JSON string), and then using JSON.parse to deserialize (restore) the js object; the function of serialization is storage and transmission. (The object itself stores an address map. If the power is off, the object will not exist, so the content of the object will be converted into a string and saved on disk.)
However, this method of deep copy has its limitations. It only applies to the copy of general data (objects, arrays). The following situations need to be noted:

1. If there is a time object in json, the serialization result is: the form of a time object => string;

{
    let obj = {
        age: 18,
        date: new Date()
    };
    let objCopy = JSON.parse(JSON.stringify(obj));
    console.log('obj', obj);
    console.log('objCopy', objCopy);
    console.log(typeof obj.date); // object
    console.log(typeof objCopy.date); // string
}

2. If there are RegExp and Error objects in json, only empty objects RegExp and Error => {} will be obtained by serialization.

{
    let obj = {
        age: 18,
        reg: new RegExp('\\w+'),
        err: new Error('error message')
    };
    let objCopy = JSON.parse(JSON.stringify(obj));
    console.log('obj', obj);
    console.log('objCopy', objCopy);
}

3. If there is function undefined in json, the result of serialization will lose function undefined.

{
    let obj = {
        age: 18,
        fn: function () {
            console.log('fn');
        },
        hh: undefined
    };
    let objCopy = JSON.parse(JSON.stringify(obj));
    console.log('obj', obj);
    console.log('objCopy', objCopy);
}

4. If there are NaN, Infinity and - Infinity in json, the result of serialization becomes null.

{
    let obj = {
        age: 18,
        hh: NaN,
        isInfinite: 1.7976931348623157E+10308,
        minusInfinity: -1.7976931348623157E+10308
    };
    let objCopy = JSON.parse(JSON.stringify(obj));
    console.log('obj', obj);
    console.log('objCopy', objCopy);
}

5. If an object in json is generated by a constructor, the serialized result discards the constructor of the object.

{
    function Person(name) {
        this.name = name;
    }
    let obj = {
        age: 18,
        p1: new Person('lxcan')
    };
    let objCopy = JSON.parse(JSON.stringify(obj));
    console.log('obj', obj);
    console.log('objCopy', objCopy);
    console.log(obj.p1.__proto__.constructor === Person); // true
    console.log(objCopy.p1.__proto__.constructor === Object); // true
}

6. If there is a circular reference in the object, deep copy cannot be achieved.

{
    let obj = {
        age: 18
    };
    obj.obj = obj;
    let objCopy = JSON.parse(JSON.stringify(obj));
    console.log('obj', obj);
    console.log('objCopy', objCopy);
}

Above, if the object of the copy does not involve the above situation, you can use JSON.parse(JSON.stringify(obj)) to achieve deep copy.
Read this article for more information on deep copy of js and Solutions The Ultimate Exploration of Deep Copies (99% of people don't know)

Keywords: Javascript JSON

Added by Isomerizer on Thu, 03 Oct 2019 22:43:34 +0300