Open sakila1012 opened 3 years ago
// 实现一个拷贝,实现一个递归拷贝
function deepClone(obj, hash = new WeakMap()){ if(obj == null) return obj; // 如果是null或者undefined,就不进行拷贝操作 if(obj instanceof Date) return new Date(obj); if(obj instanceof RegExp) return new RegExp(obj) // 可能是对象 或者普通的值,如果是函数的话,就不需要深拷贝 if(typeof obj !== 'object') return obj; // 如果是对象就进行深拷贝 if(hash.get(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] = deepClone(obj[key]) } } return cloneObj }
function isObject (target) { const type = typeof target; return target !== null && (type === 'object' || type === 'function') } function deepClone(target, cache = new WeakSet()){ if(!isObject(target)) return target; // 拷贝基本类型的值 if(cache.has(target)) return target; // 如果之前已经拷贝过该对象,直接返回该对象 cache.add(target) // 将对象添加到缓存 let cloneTarget = Array.isArray(target) ? [] : {}; Object.keys(target).forEach(key => { cloneTarget[key] = deepClone(target[key], cache) }) return cloneTarget; }
这里采用了WeakSet收集拷贝对象,WeakSet中的对象都是弱引用的,垃圾回收机制不考虑WeakSet。
上面的两个方法有啥区别呢,其实没啥区别,都是用WeakSet,WeakMap的弱引用功能,解决循环引用的问题。 我们可以开辟一个空间存储要拷贝的对象,当拷贝对象时,先去存储空间查找该对象是否被拷贝过,如果拷贝过,直接返回该对象,如果没拷贝过,就继承拷贝。
// 实现一个拷贝,实现一个递归拷贝
这里采用了WeakSet收集拷贝对象,WeakSet中的对象都是弱引用的,垃圾回收机制不考虑WeakSet。
上面的两个方法有啥区别呢,其实没啥区别,都是用WeakSet,WeakMap的弱引用功能,解决循环引用的问题。 我们可以开辟一个空间存储要拷贝的对象,当拷贝对象时,先去存储空间查找该对象是否被拷贝过,如果拷贝过,直接返回该对象,如果没拷贝过,就继承拷贝。