Points for Attention in Implementing Deep Copies of JSON.parse(JSON.stringify(obj))

Keywords: JSON Javascript Front-end github

JSON.parse(JSON.stringify(obj)) we generally use for deep copy, the process is to use JSON.stringify to serialize the js object (JSON string), and then use JSON.parse to de-serialize (restore) the js object; serialization is to store (the object itself stores only an address mapping, if the power is off, the object will no longer exist, so the content of the object needs to be converted. For example, if the requested Content-Type is application/x-www-form-urlencoded, the front-end side needs to use qs.stringify(data) to serialize the parameters and then pass them to the back-end, otherwise the back-end can not accept them; ps: Content-Type is application/json;charset=UTF-8 or multiform/part-data may not be needed; When we use JSON.parse (JSON.stringify (xxxx)), we should pay attention to several points:
1. If there is a time object in obj, the result of JSON.stringify and JSON.parse will be time only in the form of a string. It's not a time object.

      var test = {
        name: 'a',
        date: [new Date(1536627600000), new Date(1540047600000)],
      };

      let b;
      b = JSON.parse(JSON.stringify(test))
test results. png
The result of b
Testing b and test types

2. If there are RegExp and Error objects in obj, the result of serialization will only get empty objects.

      const test = {
        name: 'a',
        date: new RegExp('\\w+'),
      };
      // debugger
      const copyed = JSON.parse(JSON.stringify(test));
      test.name = 'test'
      console.error('ddd', test, copyed)
image.png

3. If there is a function in obj, undefined, the result of serialization will lose the function or undefined.

      const test = {
        name: 'a',
        date: function hehe() {
          console.log('fff')
        },
      };
      // debugger
      const copyed = JSON.parse(JSON.stringify(test));
      test.name = 'test'
      console.error('ddd', test, copyed)
image.png
image.png

4. If there are NaN, Infinity and - Infinity in obj, the serialized result will become null


image.png

5. JSON.stringify() can only serialize enumerable attributes of an object. For example, if the object in obj is generated by a constructor, the constructor of the object will be discarded after a deep copy of JSON.parse(JSON.stringify(obj)).

      function Person(name) {
        this.name = name;
        console.log(name)
      }

      const liai = new Person('liai');

      const test = {
        name: 'a',
        date: liai,
      };
      // debugger
      const copyed = JSON.parse(JSON.stringify(test));
      test.name = 'test'
      console.error('ddd', test, copyed)

image.png

6. If there are circular references in the object, the deep copy can not be realized correctly.

Above, if the object of the copy does not involve the situation mentioned above, we can use JSON.parse(JSON.stringify(obj)) to achieve deep copy, but when it comes to the above situation, we can consider the following methods to achieve deep copy:

 function  deepClone(data) {
      const type = this.judgeType(data);
      let obj;
      if (type === 'array') {
        obj = [];
      } else if (type === 'object') {
        obj = {};
      } else {
    // No longer has the next level
        return data;
      }
      if (type === 'array') {
        // eslint-disable-next-line
        for (let i = 0, len = data.length; i < len; i++) {
          obj.push(this.deepClone(data[i]));
        }
      } else if (type === 'object') {
        // The method on the prototype is also copied.
        // eslint-disable-next-line
        for (const key in data) {
          obj[key] = this.deepClone(data[key]);
        }
      }
      return obj;
    },


function  judgeType(obj) {
  // tostring returns constructors corresponding to different tags
      const toString = Object.prototype.toString;
      const map = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Object]': 'object',
      };
      if (obj instanceof Element) {
        return 'element';
      }
      return map[toString.call(obj)];
    },


Recommended information

1,JavaScript Object Serialization Explanation
2,Implementation of Shallow Copy and Deep Copy in javaScript

Posted by bryansu on Sun, 23 Dec 2018 11:18:06 -0800