对JS对象进行复制的时候,有两种拷贝方式,一种是浅拷贝,一种是深拷贝。
一 浅拷贝
浅拷贝只复制对象的第一层属性,如果属性是基本类型,则直接复制值;如果属性是引用类型,则复制其内存地址(引用)。因此,如果原始对象的基本类型属性被修改,拷贝对象的属性不会被修改;如果原始对象的引用类型属性被修改,由于拷贝对象和原始对象指向同一内存地址,拷贝对象中的相应属性也会被修改。
实现浅拷贝的方法:
- 展开运算符:{ ...obj }
- Object.assign():Object.assign({}, obj)
- 数组的slice方法(用于数组):arr.slice()
- Array.from()(用于数组):Array.from(arr)
二 深拷贝
深拷贝会复制对象的所有层级,无论对象包含基本类型还是引用类型,每一层都是新创建的值,而不是引用原始对象中的值,因此会创建一个完全独立的副本,使得原始对象和拷贝对象之间不存在任何共享的引用。
实现深拷贝的方法:
- JSON.parse(JSON.stringify(object))
- 使用递归进行深拷贝
function deepClone(target) {
if (target === null || typeof target !== 'object') {
return target;
}
// let cloneTarget = target.constructor === Array ? [] : {};
let cloneTarget = Array.isArray(target) ? [] : {};
Object.keys(target).forEach(key => {
if (target[key] && typeof target[key] === 'object') {
cloneTarget[key] = deepClone(target[key]);
} else {
cloneTarget[key] = target[key];
}
});
return cloneTarget;
}
- 使用第三方库:比如 Lodash 的 _.cloneDeep 方法
总结
深拷贝会让新对象和原始对象完全解耦,而浅拷贝的方式创建的新对象和原始对象之间还有联系。