分为五种数据类型分别对方法进行封装,代码如下
let vm = new WeakMap()
function deepClone(obj) {
// 1.基本数组类型
if(obj === null || typeof obj !== 'object') {
return obj
}
// 如果缓存中已经存在该对象则不进行操作 weakMap
if(vm.has(obj)) {
return vm.get(obj)
}
if(obj instanceof Map) {
// 2.map类型
var tmp = new Map()
vm.set(obj, tmp)
for(var values of obj) {
var key = values[0]
var value = values[1]
// 当value为引用数据类型时,递归调用
tmp.set(key, deepClone(value))
}
return tmp
} else if(obj instanceof Set) {
// 3.set类型
var tmp = new Set()
vm.set(obj, tmp)
for(var val of obj) {
// 当val为引用数据类型时,递归调用
tmp.add(deepClone(val))
}
return tmp
} else if(obj instanceof RegExp) {
// 4.正则表达式类型
var tmp = new RegExp(obj)
vm.set(obj, tmp)
return tmp
} else {
// 5. 数组、对象、Date等类型
var tmp = new obj.constructor()
vm.set(obj, tmp)
for(var key in obj) {
// 当value为引用数据类型时,递归调用
tmp[key] = deepClone(obj[key])
}
return tmp
}
}
注意:
采用用 JSON.parse(JSON.stringify(obj2))对如下的环形对象,会报错;
let obj2 = {
to: obj1
}
obj1.to = obj2
// obj1 => obj2 => obj1 => obj2 => obj1 => obj2 => obj1 环形对象
let cloned = JSON.parse(JSON.stringify(obj1))
console.log(cloned)
报错信息
采用 JSON.parse(JSON.stringify(obj1))对于function等特定数组结构无法拷贝
let obj1 = {
// typeof 数组|对象 => 'object'
// Array.isArray()
arr: [1, 2, 3],
arrayOfObjs: [{ c: 5 }, { d: 6 }],
date: new Date(),
object: { val: 4 },
// 增加一个属性
fn: function () { // typeof fn ===> 'function'
return 5;
},
set: new Set([7, 8, 9, { e: 10 }]),
map: new Map([
[11, 'f'],
[12, 'g']
]),
reg: /[h-z]/
};
let cloned = JSON.parse(JSON.stringify(obj1))
console.log(cloned);
运行结果
没有拷贝function