从具有访问器的对象创建深度克隆对象文字的最佳方法?
Best way to create a deep cloned object literal from an object with accessors?
我有一个对象,它是文字和访问器的组合:
const obj = {
stuff: [],
get processedStuff() { return this.stuff.map(el => `${el}!`) }
}
obj.stuff = ['woot']
console.log(obj.processedStuff) // ['woot!']
我想创建一个 obj 的 deepClone,以便克隆的行为完全像一个文字。所以在克隆中,对 stuff 的更改将不再导致对 processedStuff 的更改:
const obj2 = cl0n3Me(obj)
obj2.stuff = ['nope']
console.log(obj.processedStuff) // ['woot!']
在 lodash 中使用像 cloneDeep 这样的库函数并不能做到这一点——访问器是顺其自然的,并且是新对象的一部分。
我可以通过以下方式做到这一点...
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;
}
}
我有一个对象,它是文字和访问器的组合:
const obj = {
stuff: [],
get processedStuff() { return this.stuff.map(el => `${el}!`) }
}
obj.stuff = ['woot']
console.log(obj.processedStuff) // ['woot!']
我想创建一个 obj 的 deepClone,以便克隆的行为完全像一个文字。所以在克隆中,对 stuff 的更改将不再导致对 processedStuff 的更改:
const obj2 = cl0n3Me(obj)
obj2.stuff = ['nope']
console.log(obj.processedStuff) // ['woot!']
在 lodash 中使用像 cloneDeep 这样的库函数并不能做到这一点——访问器是顺其自然的,并且是新对象的一部分。
我可以通过以下方式做到这一点...
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;
}
}