1. let obj = { name:'freen',obj:{} };
let obj1 = {...obj}; //展开时是新的数据,第一层拷贝,深层无法处理
2. 开发中简易实现 (function丢失,Map/Set/Regexp数据丢失)
let obj2 = JSON.parse(JSON.stringify(obj))
console.log(obj, obj2);
3. 较完整实现
let obj1 = {
num: 12,
nulVal: null,
fn: function(){ console.log(6) },
reg: /7/,
date: Date.now(),
map: new Map([['d',8],['e',9]],[{a:1},{b:2}]),
set: new Set([10, 11]),
array: [1, 2],
arrayOfObj: [{ a: 3, b: 4}],
obj: { c: 5 },
}
//优化 弱(虚)引用,对比强引用,可以更好更快释放内存
// 针对引用数据类型做key的时候,用WeakMap,普通的Map就行
const cacheMap = new WeakMap();
const OBJECT_TYPE = '[object Object]'
function deepClone(obj) {
// 排除基本数据类型 (null / 不是对象类型) 包括function
if(typeof obj !== 'object' || !obj){
return obj;
}
// 优化,设置缓存,避免栈溢出
if (cacheMap.has(obj)) {
return cacheMap.get(obj);
}
// Map Set
// Date Regexp 需要通过构造函数传参
// 常见key Array Object
let params; //默认是个undefined
if (obj instanceof Date || obj instanceof RegExp) {
params = obj
new Date() || new RegExp();
}
let instance = new obj.constructor(params)
cacheMap.set(obj, instance); //加入到缓存
if (obj instanceof Map) {
// 加东西
for (let [key,value] of obj) {
instance.set(deepClone(key), deepClone(value));
}
} else if (obj instanceof Set) {
// 加东西
for(let value of obj){
instance.set(deepClone(key));
}
} else if (Array.isArray(obj) || Object.prototype.toString.call(obj) === OBJECT_TYPE) {
for(let k in obj){
// k不用管,常规状态下,k都是基本数据类型
instance[k] = deepClone(obj[k]);
}
}
return instance;
}