// 用JSON
const b = JSON.parse(JSON.stringfy(a))
缺点
- 不能支持 Date , 正则 , undefined , 函数等
- 不支持引用
// 用递归去实现深拷贝
const deepClone = (a,cache) => {
if(!cache) {
cache = new Map()
}
if(a instanceof Object) {
if(cache.get(a)) {return cache.get(a)}
let result
if( a instanceof Function) {
if(a.prototype) {
result = function (){return a.apply(this , arguments)}
} else {
result = (...args) => { return a.call(undefined,...args)}
}
} else if( a intanceof Array) {
result = []
} else if(a intanceof Date) {
result = new Date(a - 0)
} else if (a intanceof RegExp) {
result = new RegExp(a.source , a.flags)
} else {
result = {}
}
for( let key in a) {
if(a.hasOwnProperty(key)) {
result[key] = deepClone(a[key],cache)
}
}
return result
} else {
return a
}
}
但是这个也不是百分之百的拷贝,因为对象里可能没有符合上面的条件的键值。
function deepClone(a){
if(a instanceof Object){
let result = undefined
if(a instanceof Function){
if(a.prototype){
result = function(){return a.apply(this,args)}
}else{ // 箭头函数
result = (...args)=> {return a.call(undefined,...args)}
}
}else if(a instanceof Array){
result = new Array()
}else if(a instanceof Date){
result = new Date(a-0)
}else if(a instanceof RegExp){
result = new RegExp(a.source,a.flags)
}else{
result = {}
}
for(let key in a){
result[key] = deepClone(a[key])
}
return result
}else{
return a
}
}
第一步先判断是不是object还是其他 是Object后继续缩小范围,确定是Function、array等 然后声明一个result,根据是function、array生成不同的容器 最后遍历参数,对result做递归 返回result
上面还有一个缺陷,让a.self = a 然后 const b = deepClone(a),会不断的进行clone,不断循环,也被称作环。
下一步就是检查环,当已经把a拷贝成b了,当再拷贝 a 的时候,直接返回b
let cache = new Map()
function deepClone(a){
if(cache.get(a)){
return cache.get(a)
}
if(a instanceof Object){
let result = undefined
if(a instanceof Function){
if(a.prototype){
result = function(){return a.apply(this,args)}
}else{ // 箭头函数
result = (...args)=> {return a.call(undefined,...args)}
}
}else if(a instanceof Array){
result = new Array()
}else if(a instanceof Date){
result = new Date(a-0)
}else if(a instanceof RegExp){
result = new RegExp(a.source,a.flags)
}else{
result = {}
}
cache.set(a,result)
for(let key in a){
result[key] = deepClone(a[key])
}
return result
}else{
return a
}
}
缓存不能全局,最好临时创建并递归传递
function deepClone(a){
if(!cache){
cache = new Map()
}
if(a instanceof Object){
let result = undefined
if(cache.get(a)){
return cache.get(a)
}
if(a instanceof Function){
if(a.prototype){
result = function(){return a.apply(this,args)}
}else{ // 箭头函数
result = (...args)=> {return a.call(undefined,...args)}
}
}else if(a instanceof Array){
result = new Array()
}else if(a instanceof Date){
result = new Date(a-0)
}else if(a instanceof RegExp){
result = new RegExp(a.source,a.flags)
}else{
result = {}
}
cache.set(a,result)
for(let key in a){
result[key] = deepClone(a[key])
}
return result
}else{
return a
}
}