JSON.parse(JSON.stringify ())实现深拷贝时有什么缺点

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);

  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值