深拷贝是指创建一个新的对象或数组,该对象或数组与原始对象或数组具有相同的值,但是它们是完全独立的,即使原始对象或数组发生更改,也不会影响深拷贝后的对象或数组。深拷贝需要递归地复制所有嵌套的对象和数组,以确保所有引用都是独立的。
浅拷贝:将原对象或原数组的引用直接赋值给新对象,新对象只是一个引用。
对于一层数组解决方法
- 直接遍历
- slice()
var array = [1, 2, 3, 4];
var copyArray = array.slice();
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]
- concat()
var array = [1, 2, 3, 4];
var copyArray = array.concat();
copyArray[0] = 100;
console.log(array); // [1, 2, 3, 4]
console.log(copyArray); // [100, 2, 3, 4]
对于一层的对象解决方法
- 直接遍历
- Object.assign()
- 扩展运算符
JSON.stringify()方式
JSON.parse(JSON.stringify())
问题:
JSON.stringify()只能序列化对象的可枚举的自有属性,例如如果对象中的属性是函数、RegExp对象、Date对象等特殊对象类型,则在序列化过程中会丢失这些属性。此外,如果对象中的属性值是undefined、Symbol类型,则在序列化过程中会被忽略掉
Date对象拷贝后只是时间,不是对象形式了
RegExp对象、Error 对象,则序列化的结果将只得到空对象;
如果 obj 里有函数(function),undefined,Symbol 则序列化的结果会丢失;
如果obj里有 NaN、Infinity 和 -Infinity,则序列化的结果会变成 null
递归方式(全能)
//使用递归的方式实现数组、对象的深拷贝
function deepClone (obj) {
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === "object") {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
//判断ojb子元素是否为对象,如果是,递归复制
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]);
} else {
//如果不是,简单复制
objClone[key] = obj[key];
}
}
}
}
return objClone;
};
其他
- 使用第三方库如lodash中的cloneDeep()方法
- JQuery的extend()函数