修改嵌套对象时应该深拷贝吗?

Should I deep copy when modifying nested object?

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

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

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

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

两个对象都已更改。所以我想知道在这种情况下我是否应该使用深拷贝,或者使用一些第三方不可变数据结构,或者是否有其他解决方案?

你是对的,浅拷贝没有帮助,但你不需要完整深拷贝,你只需要复制你想要的东西改变。在您的情况下,这是 personparentsdad,但不是 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
            }
        }
    };
};

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