JSON.parse(JSON.stringify ())在实现深拷贝时是有一些弊端的。

有以下几种情况时,不能正确的进行深拷贝:

1、obj里面有new Date(),深拷贝后,时间会变成字符串的形式。而不是时间对象;

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

   let b;
   b = JSON.parse(JSON.stringify(a))
console.log(a,b)

在这里插入图片描述
2、obj里有RegExp、Error对象,则序列化的结果会变成空对象{};

const a = {
     name: 'a',
     date: new RegExp('\\w+'),
   };
   // debugger
 const b = JSON.parse(JSON.stringify(a));
 a.name = 'test'
 console.log( a, b)

在这里插入图片描述
3、obj里有function,undefined,则序列化的结果会把function或 undefined丢失;

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

在这里插入图片描述
4、obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null;

const a = {
        name: 'a',
        date: NaN,
      };
      // debugger
      const b = JSON.parse(JSON.stringify(a));
      a.name = 'test'
      console.log(a, b)

在这里插入图片描述
5、JSON.stringify()只能序列化对象的可枚举的自有属性,如果obj中的对象是由构造函数生成的实例对象, 深拷贝后,会丢弃对象的constructor

function Person(name){
    this.name=name;
}
var person = new Person('jyy')
const a = {
        name: 'a',
        date: person,
      };
      // debugger
const b = JSON.parse(JSON.stringify(a));
a.name = 'test'
console.log(a, b)

在这里插入图片描述

6、如果对象中存在循环引用的情况也无法正确实现深拷贝;
那么, 以上的6种情况怎么实现深拷贝呢?看下面的代码:

//实现深拷贝函数
function deepClone(data) {
    const type = this.judgeType(data);
    let obj = null;
    if (type == 'array') {
        obj = [];
        for (let i = 0; i < data.length; i++) {
            obj.push(this.deepClone(data[i]));
        }
    } else if (type == 'object') {
        obj = {}
        for (let key in data) {
            if (data.hasOwnProperty(key)) {
                obj[key] = this.deepClone(data[key]);
            }
        }
    } else {
        return data;
    }
    return obj;
}

function judgeType(obj) {
    // tostring会返回对应不同的标签的构造函数
    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)];
}
const test = {
    name: 'a',
    date: [1,2,3]
};


console.log(deepClone(test))
test.date[0] = 6;
console.log(test);

GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e 3 个月前
8c391e04 6 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐