我们在面试的时候,可能会被要求实现一个深拷贝。
这其实是一个高频的手写题:
// 利用 WeakMap 解决循环引用 let map = new WeakMap() function deepClone(obj) { if(obj instanceof Object) { if(map.has(obj)) { return map.get(obj) } let newObj if(obj instanceof Array) { newObj = [] } else if(obj instanceof Function) { newObj = function() { return obj.apply(this, arguments) } } else if(obj instanceof RegExp) { // 拼接正则 newobj = new RegExp(obj.source, obj.flags) } else if(obj instanceof Date) { newObj = new Date(obj) } else { newObj = {} } // 克隆一份对象出来 let desc = Object.getOwnPropertyDescriptors(obj) let clone = Object.create(Object.getPrototypeOf(obj), desc) map.set(obj, clone) for(let key in obj) { if(obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key]) } } return newObj } return obj }
以上代码解决了常见类型的copy和循环引用的问题。
不过瑕疵还是有的,例如递归肯定会存在爆栈的问题,因为执行栈的大小是有限制的,到一定数量栈就会爆掉。
如果遇到这种问题,解决之道就是:用遍历的方式来改写递归。也就是如何写层序遍历(BFS)的问题了,只需要通过数组来模拟执行栈就能解决。
在面试的时候如果被要求手写深拷贝,能写出上面的代码已经完全够了,剩下的能口述思路基本上这道题就能拿到高分。