一 普通的object.assign 或者扩展符...只能对基本类型值拷贝后互不影响,但是引用类型还是会影响
a = {
x: 2,
y: [1]
}
b = Object.assign({}, a) || {...a}
b // {
x: 2,
y: [1]
}
b.x = 99
b.y.push(2)
b // {
x: 99,
y: [1, 2]
}
a // {
x: 2,
y: [1, 2]
}
二 或者通过JSON.stringify实现深拷贝
但是有几点要注意
- 拷贝的对象的值中如果有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失
- 无法拷贝不可枚举的属性,无法拷贝对象的原型链
- 拷贝Date引用类型会变成字符串
- 拷贝RegExp引用类型会变成空对象
- 对象中含有NaN、Infinity和-Infinity,则序列化的结果会变成null
- 无法拷贝对象的循环应用(即obj[key] = obj)
三 最好是递归。
递归1
function deepCopy(newObj, oldObj) {
for (var key in oldObj) {
var item = oldObj[key]
if (item instanceof Array) {
newObj[key] = [];
deepCopy(newObj[key], item);
} else if (item instanceof Object) {
newObj[key] = {};
deepCopy(newObj[key], item);
} else {
newObj[key] = item;
}
}
return newObj;
}
递归2
function deepClone(obj) {
if (Object.prototype.toString.call(obj).slice(8, -1) === 'Object') {
var newObj = {}
for (const key in obj) {
newObj[key]=deepClone(obj[key])
}
return newObj
} else if (Object.prototype.toString.call(obj).slice(8, -1) === 'Array') {
var newArr = []
for (const index in obj) {
newArr[index]=deepClone(obj[index])
} return newArr
}
return obj
}