浅拷贝
创建一个新对象,这个对象有这原始对象属性值的一份精确拷贝。如果属性是基本数据类型,拷贝的就是基本类型的值,如果是引用类型,拷贝的就是内存地址。所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
// 浅克隆的方法如下
Object.assign(target,...source)
let target = {};
let source = {a:{b:2}}
Object.assign(target,source);
target.a === source.a //true
深拷贝
将一个对象从内存中完成的拷贝一份出来,从堆内存中开辟一个新的区域存放新的对象,且修改新对象不会影响原对象。
const isComplexDataType = obj => typeof obj === "object";
const deepClone = function(obj, hash = new WeakMap()) {
if (hash.has(obj)) return hash.get(obj);
let type = [Date, RegExp, Set, Map, WeakMap, WeakSet];
if (type.includes(obj.constructor)) return new obj.constructor(obj);
// 如果成环了,参数obj = obj.loop = 最初obj会在WeakMap中找到第一次放入的obj提前返回,第一次放入WeakMap的cloneObj
// 遍历传入参数所有键的特性
let allDesc = Object.getOwnPropertyDescriptors(obj);
// 继承原型
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);
hash.set(obj, cloneObj);
for (let key of Reflect.ownKeys(obj)) {
// Reflect.ownKeys(obj)可以拷贝不可枚举属性和符号类型
// 如果值是引用类型(非函数)则递归调用deepClone
cloneObj[key] =
isComplexDataType(obj[key]) && typeof obj[key] !== "function"
? deepClone(obj[key], hash)
: obj[key];
}
return cloneObj;
};