浅拷贝 : 只是将数据中所有的数据引用下来,依旧指向同一个存放地址,拷贝之后的数据修改之后,也会影响到原数据的中的对象数据。例如:Object.assign(),…扩展运算符
深拷贝: 将数据中所有的数据拷贝下来,对拷贝之后的数据进行修改不会影响到原数据。。
JSON.parse(JSON.stringify(obj))深拷贝的问题
const newState = Object.assign({}, state)和JSON.parse(JSON.stringify(obj))都是可以用来深拷贝 但是也会出现下面的问题
- 如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象变成了字符串。
- 如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。
- 如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。
- 如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。
- JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的,
则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。
如果对象中存在循环引用的情况也无法正确实现深拷贝。
function Person (name) {
this.name = 20
}
const lili = new Person('lili')
let a = {
data0: '1',
date1: [new Date('2020-03-01'), new Date('2020-03-05')],
data2: new RegExp('\\w+'),
data3: new Error('1'),
data4: undefined,
data5: function () {
console.log(1)
},
data6: NaN,
data7: lili
}
// 合并对象
// const newState = Object.assign({}, state)
// 先石化 再解封 就重新开辟空间了
let b = JSON.parse(JSON.stringify(a))
12345678910111213141516171819202122
执行结果
解决方法:
可以使用 lodash 库来解决
//lodash
// 这个库 解决了 javascript中的 疑难杂症 比如深拷贝 npm insall loadsh
//const { cloneDeep } = require('lodash')
123