Javascript 实现深拷贝有几种方式
- 对于基本类型比如字符串、数字等默认赋值就是深拷贝。
- 对于引用类型,比如对象、数组,默认赋值是浅拷贝,即改变一个变量值,另一个也会改变,它们的深拷贝有两种情况:
let a = [1, 2, 3];
let aa = [...a];
a[0] = 99;
console.log(a, aa);
let b = {test: 1, ok: 2};
let bb = {...b};
// 或者 let bb = Object.assign({}, b)
b.ok = 3;
console.log(b, bb);
- 被更改对象、数组超过一层
- 元素只有基本类型,可以使用JSON.stringify/parse
// 被更改部分处于第二层,Object.assign无法深拷贝
let b = {test: {a: 22}, ok: 2};
let bb = Object.assign({}, b)
b.test.a = 3;
console.log(b, bb);
// 被更改部分处于第一层,Object.assign可以深拷贝
bb = Object.assign({}, b)
b.ok = 3;
console.log(b, bb);
// 使用JSON字符串解析实现深拷贝
let bbb = JSON.parse(JSON.stringify(b));
b.test.a = 4;
console.log(b, bbb);
通用深拷贝方法
function deepCopy(target) {
let newTarget = null;
if (Object.prototype.toString.call(target) !== "[object Array]" && Object.prototype.toString.call(target) !== "[object Object]") {
return target;
}
newTarget = Array.isArray(target) ? [] : {};
if (Object.prototype.toString.call(target) === "[object Array]") {
for (const data of target) {
newTarget.push(deepCopy(data));
}
} else {
for (const key of Object.keys(target)) {
newTarget[key] = deepCopy(target[key]);
}
}
return newTarget;
}
使用:let a = {test: 1}; let aa = deepCopy(a);