浅拷贝和深拷贝
浅拷贝
浅拷贝是与拷贝源对象共享相同的引用值,因此,当源对象发生变化时,拷贝对象也会发生变化。
深拷贝
深拷贝中,源和副本是完全独立的。
深拷贝是与拷贝源对象不共享相同的引用值,因此,当源对象发生变化时,拷贝对象不会发生变化。
如何实现深拷贝
JSON.parse() 和 JSON.stringify()
通过将对象转换为 JSON 字符串,然后再将字符串解析为对象是一种简单快速的深拷贝方法。
但是在转换的过程中,会丢失对象的原型链,因此,无法拷贝函数、日期对象、正则对象、undefined 等数据。
ts
const copyOfJSON = JSON.parse(JSON.stringify(obj));
递归
如果对象中包含复杂的数据类型(函数、循环引用等),可以使用递归函数来实现深拷贝,这种方法更为通用。
ts
function deepCopy(obj: any, hash = new WeakMap()) {
if (obj === null) return null;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (typeof obj !== "object") return obj;
if (hash.has(obj)) return hash.get(obj);
let cloneObj = new obj.constructor();
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepCopy(obj[key], hash);
}
}
return cloneObj;
}
const copyOfDeep = deepCopy(obj);
第三方库
使用第三方库,如 lodash 的 cloneDeep()
方法,可以实现深拷贝。
ts
import _ from "lodash";
const copyOfLodash = _.cloneDeep(obj);