weakMap 的关键区别,这里要用 weakMap),作为检测循环引用很有帮助,如果存在循环,则引用直接返回 WeakMap 存储的值。
代码实现如下:
const deepClone = function (obj, hash = new WeakMap()) {
if (obj.constructor === Date) return new Date(obj) // 日期对象直接返回一个新的日期对象
if (obj.constructor === RegExp) return new RegExp(obj) //正则对象直接返回一个新的正则对象
if (hash.has(obj)) return hash.get(obj) //如果循环引用了就用 weakMap 来解决
let allDesc = Object.getOwnPropertyDescriptors(obj) //遍历传入参数所有键的特性
let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc) //继承原型链
hash.set(obj, cloneObj);
for (let key of Reflect.ownKeys(obj)) {
cloneObj[key] = (isComplexDataType(obj[key]) && typeof obj[key] !== 'function') ? deepClone(obj[key], hash) : obj[key]
return cloneObj;
function clone(obj) {
let map = new WeakMap()
function deep(data) {
let result = {}
const keys = [...Object.getOwnPropertyNames(data), ...Object.getOwnPropertySymbols(data)]
if(!keys.length) return data
const exist = map.get(data)
if (exist) return exist
map.set(data, result)
keys.forEach(key => {
let item = data[key]
if (typeof item === 'object' && item) {
result[key] = deep(item)
} else {
result[key] = item
})
return result
return deep(obj)