浅拷贝
创建一个新对象,这个对象有这原始对象属性值的一份精确拷贝。如果属性是基本数据类型,拷贝的就是基本类型的值,如果是引用类型,拷贝的就是内存地址。所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
// 浅克隆的方法如下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)可以拷贝不可枚举属性和符号类型// 如果值是引用类型(非函数)则递归调用deepClonecloneObj[key] =isComplexDataType(obj[key]) && typeof obj[key] !== "function"? deepClone(obj[key], hash): obj[key];}return cloneObj;};
