deepClone 深拷贝
js
// 解决循环引用的方案
// https://www.jianshu.com/p/93bc862e8e0d
// 弱引用
// https://github.com/chaos-zhu/Es5678910-study/issues/5
// JSON.parse(JSON.stringify(obj)) 缺陷:1、无法处理函数、symbol、正则;2、循环引用报错
function deepClone(obj, map = new WeakMap()) {
if(typeof(obj) !== 'object' || typeof(obj) === null) return obj
if(obj instanceof Function) return obj
if(obj instanceof RegExp) return obj
if(obj instanceof Date) return obj
// 解决循环引用的问题
if(map.get(obj)) return obj
map.set(obj, obj)
let res = Array.isArray(obj) ? [] : {}
for(let key in obj) {
if(obj.hasOwnProperty(key)) res[key] = deepClone(obj[key], map)
}
return res
}
let obj1 = {
name: 'tom',
age: 19,
other: {
city: ['sz', "gg"],
sex: 'man'
},
fn: function () {return 1},
date: new Date(),
sym: Symbol(),
reg: new RegExp('\\w+'),
}
let obj2 = deepClone(obj1)
obj1.name = 'chaos'
obj1.other.city[1] = 'hz'
obj1.other.sex = 'woman'
console.log(obj2)
判断更简单点的版本
js
function type(val) {
const [, res] = Object.prototype.toString.call(val).match(/\[object\s(.+)\]/) // 加g修饰符返回的又是另外一个结果了https://chaoszhu.com/front-end/regexp/js%E5%B8%B8%E7%94%A8%E6%AD%A3%E5%88%99API.html#match-%E5%92%8C-matchall
return res.toLowerCase()
}
// console.log(type(''))
function deepClone(obj, map = new WeakMap()) {
console.log(type(obj))
if(!(['object', 'array'].includes(type(obj)))) return obj // 获取直接判断: !(Array.isArray(obj) || typeof(obj) === 'object')
if(map.get(obj)) return obj
map.set(obj, obj)
let res = Array.isArray(obj) ? [] : {}
for (const key in obj) {
console.log(obj[key])
if(obj.hasOwnProperty(key)) res[key] = deepClone(obj[key], map)
}
return res
}
let o = {
a: 1,
b: {a: 2},
c: new Date(),
d: new RegExp('/a/'),
f: () => {}
}
let deepO = deepClone(o)
console.log(deepO === o)