为什么要深拷贝
因为js有引用数据类型,引用数据类型是以地址的形式存在数据中。直接赋值后修改其值,所有复制的值都会变。
利用JSON转一下不香么?
JSON.parse(JSON.stringify(data))
日期、NAN、undefined、函数、正则等有问题
利用扩展运算符不香么?
{...obj}
[...arr]
不能深度拷贝
手写深拷贝
随手拈来的版本
除了object的typeof为object外,null的typeof也为object
function copy(target) {
if (target && typeof target === 'object') {
if (target instanceof Array) {
let arr = [];
target.forEach((item, index) => {
arr[index] = copy(item);
});
return arr;
}
let obj = {};
for (let key in target) {
obj[key] = copy(target[key]);
}
return obj;
}
return target;
}
因为在typeof target === 'object‘里只判断了数组类型,所以上述方法只能复制引用数据类型为对象和数组的数据。
进阶版本
array、date、regExp等数据的typeof也为object,这里借用Object.prototype.toString获取准确的数据类型
function copy(target) {
switch (Object.prototype.toString.call(target).slice(8, -1)) {
case 'Object':
let obj = {};
for (let key in target) {
obj[key] = copy(target[key]);
}
return obj;
case 'Array':
let arr = [];
target.forEach((item, index) => {
arr[index] = copy(item);
});
return arr;
default:
return target;
}
}
当然上面的精确判断对象是对象的方法也可以换成别的,比如 target.constructor === Object