面试之手写深拷贝
前言
作为一位正在准备跳槽的程序员,我们来手写一下深拷贝,深拷贝是面试的经典问题,我们来实现一下深拷贝,记录生活记录美~
深拷贝
首先让我们来试一下标准版
const deepClone = function (target, map = new WeakMap()) {
// 检查是否存在循环引用,没处理的话,遇到这种情况很容易爆栈
// 使用WeakMap,是为了让对象处于弱引用,直接被垃圾回收
if(map.has(target)) return map.get(target)
// 首先判断是否是一个数组还是对象分别处理
let cloneTarget = Array.isArray(target)?[]:{};
// 检查是下面的哪种类型,我们可以通过对象的构造重新创建
let type = [RegExp,Date, Map, Set, WeakMap, WeakSet]
if(type.includes(target.constructor)) return new target.constructor(target)
// 将对象缓存到map中,解决循环引用
map.set(target, cloneTarget)
// Reflect.ownKeys方法可以将对象上面的所有键都取出来,包括Symbol
for(const key of Reflect.ownKeys(target)) {
cloneTarget[key] = (typeof target[key] === 'object' && target[key] !== null)
// 每次遍历需要将map传入
? deepClone(target[key],map) : target[key]
}
return cloneTarget
}
继续让深入完整版
const deepClone = function(target, map=new WeakMap()) {
if(map.has(target)) return map.get(target)
let type = [Date, RegExp, Set, Map, WeakMap, WeakSet]
if(type.includes(target.constructor)) return new target.constructor(target)
let allDes = Object.getOwnPropertyDescriptors(target)
let cloneTarget = Object.create(Object.getPrototypeOf(target), allDes)
map.set(target, cloneTarget)
for(let key of Reflect.ownKeys(target)) {
cloneTarget[key] = (typeof target[key] === 'object' && target[key] !== null)
? deepClone(target[key], map)
: target[key]
}
return cloneTarget
}
结尾
搞懂这两个版本的深拷贝,相信大家对面试深拷贝不在话下了,喜欢的小伙伴,可以点赞喔~