修改嵌套对象时是否应该进行深复制?

Djo*_*vic 2 javascript functional-programming immutability

我最近开始学习 Javascript 函数式编程,其中很有价值的一件事是不变性。保持不变性的一种方法是,当我们想要修改某个对象时,我们首先创建一个副本,然后修改该副本并返回它,例如:

const person = {
    firstName: 'John',
    lastName: 'Smith',
}

const modifyFName = obj => {
    const objCopy = {...obj};
    objCopy.firstName = 'James';
    return objCopy;
}

console.log(modifyFName(person)) // {firstName: 'James', lastName: 'Smith'}
console.log(person) // {firstName: 'John', lastName: 'Smith'}
Run Code Online (Sandbox Code Playgroud)

但是,如果我想修改一些深层嵌套的对象,创建像上面这样的浅拷贝不会有太大的区别,例如:

const person = {
    firstName: 'John',
    lastName: 'Smith',
    parents: {
        mom: {
            firstName: 'Jennifer',
            lastName: "Swift"
        },
        dad: {
            firstName: 'Tom',
            lastName: 'Cartman'
        }
    }
}

const modifyDadName = obj => {
    const objCopy = {...obj};
    objCopy.parents.dad.firstName = 'Aurelion';
    return objCopy;
}

console.log(modifyDadName(person)) // {... dad: "Aurelion"}
console.log(person) // {... dad: "Aurelion"}
Run Code Online (Sandbox Code Playgroud)

两个对象都发生了变化。所以我想知道在这种情况下我是否应该使用深层复制,或者可能使用一些第三方不可变数据结构,或者是否有其他解决方案?

T.J*_*der 5

你是对的,浅拷贝没有帮助,但你不需要完整的深拷贝,你只需要复制你想要改变的东西。在你的情况下,这是person, parents, 和dad,但不是mom

const modifyDadName = obj => {
    return {                            // Replacement `obj` (`person`)
        ...obj,
        parents: {                      // Replacement `obj.parents`
            ...obj.parents,
            dad: {                      // Replacement `obj.parents.dad`
                ...obj.parents.dad,
                firstName: "Aurelion",  // New name
            }
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

dad改变是因为,这就是我们正在做的操作(改变firstName)。:-)parents更改是因为更改dad意味着其属性上有一个新对象dadperson( obj) 发生变化,因为有一个新parents对象。但mom不会改变,所以我们可以重用同一个对象。