JS深拷贝实现
我发现很多javascript程序员在实现对象深拷贝的时候,主要有两种方式:
- JSON序列化与序列化解析
- 第三方库-loadash-es
JSON序列化与序列化解析
这种方式的实现其实算简单高效,但是不能覆盖很多场景,比如当目标中存在function时没法还原解析,会报错;
let a= {name: 'a'}; let a_copy= JSON.parse(JSON.stringtify(a)); //只有值和对象时OK
let a= {name: 'a', log: data=>{console.log(data)}};
let a_copy= JSON.parse(JSON.stringtify(a));
a_copy.log(123); //报错
第三方库-loadash
import {deepClone} from 'loadash';
let a= {name: 'a',log: data=>{console.log(data)}};
let a_copy= deepClone(a);
a_copy.log(123); //ok
这个方法可以支持JSON方法的不足,但是需要引入第三方库,我个人不是很喜欢,我喜欢自己造轮子。
自己实现
/**
* @todo 深拷贝
* @params {Object|Array} ob - 拷贝的对象
* @return {Object|Array}
* */
function deepClone(ob){
let _new= Array.isArray(ob)? [] : {}
function isObject(data){
return data.constructor.prototype.toString() === '[object Object]'
}
function copy(sob, _snew){
if(Array.isArray(sob)){ //数组
sob.forEach( (item,index) => {
if(item && isObject(item)){
copy(item, _snew[index]={})
}else if(item && Array.isArray(item)){
copy(item, _snew[index]=[])
}else{
_snew[index]= item
}
})
}else{ //对象
let keys = Object.keys(sob)
keys.forEach(key => {
if(sob[key] && isObject(sob[key])){ //对象
_snew[key]={}
copy(sob[key], _snew[key])
}else if(sob[key] && Array.isArray(sob[key])){ //数组
copy(sob[key], _snew[key]=[])
}else{
_snew[key]= sob[key]
}
})
}
}
copy(ob, _new)
return _new
}