浅拷贝
对象的浅拷贝是其属性与拷贝源对象的属性共享相同引用(指向相同的底层值)的副本。因此,当你更改源或副本时,也可能导致其他对象也发生更改——也就是说,你可能会无意中对源或副本造成意料之外的更改。这种行为与深拷贝的行为形成对比,在深拷贝中,源和副本是完全独立的。
object.assign:
let outObj = {
inObj: {a: 1, b: 2}
}
let newObj = {...outObj}
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}
扩展运算符:
let outObj = {
inObj: {a: 1, b: 2}
}
let newObj = Object.assign({}, outObj)
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}
concat :
//只能用于数组
const arr = [1, 2, 3, { a: 1 }];
const newArr = arr.concat();
newArr[1] = 0;
console.log(arr); // [ 1, 2, 3, {a: 1} ]
console.log(newArr); // [ 1, 0, 3, { a: 1 } ]
newArr[3].a = 4;
console.log(arr); // [ 1, 2, 3, {a: 4} ]
console.log(newArr); // [ 1, 0, 3, {a: 4} ]
slice :
const arr = [1, 2, { val: 4 }];
const newArr = arr.slice();
newArr[2].val = 5;
newArr[1] = 3;
console.log(arr); //[ 1, 2, { val: 5 } ]
console.log(newArr); //[ 1, 3, { val: 5 } ]
深拷贝
对象的深拷贝是指其属性与其拷贝的源对象的属性不共享相同的引用(指向相同的底层值)的副本。因此,当你更改源或副本时,可以确保不会导致其他对象也发生更改;也就是说,你不会无意中对源或副本造成意料之外的更改。这种行为与浅拷贝的行为形成对比,在浅拷贝中,对源或副本的更改可能也会导致其他对象的更改(因为两个对象共享相同的引用)。
JSON
const obj = {name:123}
let objClone = JSON.parse(JSON.stringify(obj));
拷贝的对象中如果有函数,undefined,symbol,当使用过JSON.stringify()进行处理之后,都会消失。
递归实现
function deepClone(obj) {
// 数据类型为引用数据类型
if (typeof obj === 'object') {
// 初始化返回结果
let result = Array.isArray(obj)? []: {};
for (let key in obj) {
// 避免相互引用出现死循环导致爆栈
if (obj === obj[key]) {
continue
}
if (obj.hasOwnProperty(key)) {
// 递归调用
result[key] = deepClone(obj[key])
}
}
return result;
} else {
// 基本数据类型,直接返回
return obj
}
}
没法拷贝一些特殊对象(如 new Map() )