从带有访问器的对象创建深度克隆对象文字的最佳方法?

问题描述

我有一个对象,它是文字和访问器的组合:

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,没有缺点,但可能是错误的。在我的测试中,它适用于您的示例。应该注意的是,这不是一个完整的深度克隆解决方案,因为它不会处理 DateMap 克隆,而没有额外的代码来处理这些类型。

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;
    }
}