问题描述
const obj = {
stuff: [],get processedStuff() { return this.stuff.map(el => `${el}!`) }
}
obj.stuff = ['woot']
console.log(obj.processedStuff) // ['woot!']
我想创建一个 obj 的 deepClone,以便克隆的行为完全像一个文字。因此,在克隆中,对内容的更改将不再导致对已处理的内容的更改:
const obj2 = cl0n3Me(obj)
obj2.stuff = ['nope']
console.log(obj.processedStuff) // ['woot!']
在 lodash 中使用像 cloneDeep 这样的库函数并不能做到这一点——访问器是为了搭便车并且是新 obj 的一部分。
我可以通过以下方式做到这一点...
const obj2 = JSON.parse(JSON.stringify(obj))
javascript 高手怎么说?
解决方法
您可以使用 destructuring assignment 进行深度克隆。 afaik,没有缺点,但可能是错误的。在我的测试中,它适用于您的示例。应该注意的是,这不是一个完整的深度克隆解决方案,因为它不会处理 Date
或 Map
克隆,而没有额外的代码来处理这些类型。
function clone( o ) {
if(Array.isArray(o)){
const o2 = [...o];
for(let i=0;i<o2.length;i++){
if(typeof o2[i]==='object'&&o2[i]!==null){
o2[i]=clone(o2[i]);
}
}
return o2;
}else{
const o2 = {...o};
for(let k in o2){
if(typeof o2[k]==='object'&&o2[k]!==null){
o2[k]=clone(o2[k]);
}
}
return o2;
}
}