在使用JSON.parse(JSON.stringify(obj))的时候会遇到一个问题,那就是对象的不可遍历属性无法复制,例如:
var obj={
a:1,
set num(value){
this.a=value;
},
get num(){
return this.a;
},
b:{
a:1,
set num(value){
this.a=value;
},
get num(){
return this.a;
},
b:{
a:1,
set num(value){
this.a=value;
},
get num(){
return this.a;
}
}
}
};
console.log(obj,JSON.parse(JSON.stringify(obj)));
在打印结果中我们可以看出,JSON.parse打印的结果中并没有set/get,因为set/get是不可遍历属性,而以上方法只能将可遍历的深复制,下面就来写一个方法解决这个问题
function objectClone(targetObj,sourceObj){
var names=Object.getOwnPropertyNames(sourceObj);
for(var i=0;i<names.length;i++){
var desc=Object.getOwnPropertyDescriptor(sourceObj,names[i]);
if(typeof(desc.value)==="object" && desc.value!==null){
var obj={};
Object.defineProperty(targetObj,names[i],{
configurable:desc.configurable,
enumerable:desc.enumerable,
writable:desc.writable,
value:obj
});
objectClone(obj,desc.value);
}else{
Object.defineProperty(targetObj,names[i],desc)
}
}
return targetObj;
}
下面来验证一下有没有成功
var objs=objectClone({},obj);
objs.b.b.num=100;
console.log(obj,objs)
可以看出修改了objs中的数据而原对象不变 ,并且set/get也被复制了。