const isobject = (val) => typeof val === 'object' && val !== null;
先简单实现一个深拷贝:
function deepClone(souce){
// 判断是不是对象,不是则直接返回
if(!isobject(souce)){
return souce;
}
var target = Array.isArray(souce) ? []:{}
for(let i in souce){
if(Object.prototype.hasOwnProperty.call(souce,i)){
let val = souce[i]
target[i] = isobject(val) ? deepClone(val) : val
}
}
return target;
}
此时这个拷贝方法不能处理循环引用的情况,增加weakMap;
function deepClone(souce, Map = new WeakMap()){
// 判断是不是对象,不是则直接返回
if(!isobject(souce)){
return souce;
}
// map中已存有该引用对象则直接取值
if(Map.has(souce))return Map.get(souce);
var target = Array.isArray(souce) ? []:{}
// 将需要克隆的对象作为key,克隆生成的对象做value存储
Map.set(souce,target)
for(let i in souce){
if(Object.prototype.hasOwnProperty.call(souce,i)){
let val = souce[i]
target[i] = isobject(val) ? deepClone(val , Map) : val
}
}
return target;
}
拷贝symbol属性:
function deepClone(souce, Map = new WeakMap()){
// 判断是不是对象,不是则直接返回
if(!isobject(souce)){
return souce;
}
// map中已存有该引用对象则直接取值
if(Map.has(souce))return Map.get(souce);
var target = Array.isArray(souce) ? []:{}
// 将需要克隆的对象作为key,克隆生成的对象做value存储
Map.set(souce,target)
// 查看对象有没有symbol属性,有则克隆;
const symbolkey = Object.getOwnPropertySymbols(souce)
if(symbolkey.length){
symbolkey.forEach(key => {
let val = souce[key]
target[key] = isobject(val) ? deepClone(val,Map) : val
})
}
for(let i in souce){
if(Object.prototype.hasOwnProperty.call(souce,i)){
let val = souce[i]
target[i] = isobject(val) ? deepClone(val,Map) : val
}
}
return target;
}
克隆日期与正则类型
function deepClone(souce, Map = new WeakMap()){
// 判断是不是对象,不是则直接返回
if(!isobject(souce)){
return souce;
}
if(Object.prototype.String.call(souce).slice(8,-1) === 'Date'){
return new Date(souce)
}
if(Object.prototype.String.call(souce).slice(8,-1) === 'RegExp'){
return new RegExp(souce)
}
// map中已存有该引用对象则直接取值
if(Map.has(souce))return Map.get(souce);
var target = Array.isArray(souce) ? []:{}
// 将需要克隆的对象作为key,克隆生成的对象做value存储
Map.set(souce,target)
// 查看对象有没有symbol属性,有则克隆;
const symbolkey = Object.getOwnPropertySymbols(souce)
if(symbolkey.length){
symbolkey.forEach(key => {
let val = souce[key]
target[key] = isobject(val) ? deepClone(val,Map) : val
})
}
for(let i in souce){
if(Object.prototype.hasOwnProperty.call(souce,i)){
let val = souce[i]
target[i] = isobject(val) ? deepClone(val,Map) : val
}
}
return target;
}
深拷贝
在实现深拷贝前,先实现一个判断Object的方法:
先简单实现一个深拷贝:
此时这个拷贝方法不能处理循环引用的情况,增加
weakMap
;拷贝
symbol
属性:克隆日期与正则类型