Javascript 需要自定义分配实现吗

Javascript 需要自定义分配实现吗,javascript,immutability,Javascript,Immutability,我正在使用一些状态管理应用程序,其中的数据结构如下 const mainObject = { firstLevel: { secondLevel: { thirdLevel: { actualProperty: 'Secret' } } }, firstLevelUntouched:{ secondLevelUntouched:{

我正在使用一些状态管理应用程序,其中的数据结构如下

const mainObject = {
    firstLevel: {
        secondLevel: {
            thirdLevel: {
                actualProperty: 'Secret'
            }
        }
    },
    firstLevelUntouched:{
        secondLevelUntouched:{
            thirdLevelUntouched:{
                untouchedProperty:'I don`t want to change'
            }
        }
    }
};
我想将actualProperty更改为一个新值,该值将生成一个deepClone

我是用下面的代码做的

const modified = {
    ...mainObject,
    ...{
        firstLevel: {
            ...mainObject.firstLevel,
            ...{
                secondLevel: {
                    ...mainObject.firstLevel.secondLevel,
                    thirdLevel: {
                        ...mainObject.firstLevel.secondLevel.thirdLevel,
                        actualProperty: 'New secret'
                    }
                }
            }
        }
    }
}
但它看起来像是庞大的代码。所以我需要写一个函数,比如

modified=myCustomAssignment(主对象,['firstLevel','secondLevel','thirdLevel','actualProperty'],'New secret')


有人能帮我吗?

您可以使用一个简单的遍历函数来遍历传递的属性,直到它作为最终属性到达,然后将其设置为新值

function myCustomAssignment(mainObject, propertyList, newValue) {
   const lastProp = propertyList.pop();
   const propertyTree = propertyList.reduce((obj, prop) => obj[prop], mainObject);
   propertyTree[lastProp] = newValue;
}

您甚至可以将
propertyList=propertyList.split('.')
添加到此函数的顶部,以便可以将列表作为易于读取的字符串传入,如
myCustomAssignment(main对象,'firstLevel.secondLevel.thirdLevel.actualProperty','new value')
如果您需要的话。

您可以使用一个简单的遍历函数来进行此操作,该函数只遍历传递的属性,直到它作为最终属性到达,然后将其设置为新值

function myCustomAssignment(mainObject, propertyList, newValue) {
   const lastProp = propertyList.pop();
   const propertyTree = propertyList.reduce((obj, prop) => obj[prop], mainObject);
   propertyTree[lastProp] = newValue;
}
export function mutateState(mainObject: object, propertyList: string[], newValue: any) {
    const lastProp = propertyList.pop();
    const newState: object = { ...mainObject };
    const propertyTree =
        propertyList
            .reduce((obj, prop) => {
                obj[prop] = { ...newState[prop], ...obj[prop] };
                return obj[prop];
            }, newState);
    propertyTree[lastProp] = newValue;
    return newState as unknown;
}
您甚至可以将
propertyList=propertyList.split('.')
添加到此函数的顶部,以便可以将列表作为易于阅读的字符串传入,如
myCustomAssignment(main对象,'firstLevel.secondLevel.thirdLevel.actualProperty','new value')
,如果需要的话

export function mutateState(mainObject: object, propertyList: string[], newValue: any) {
    const lastProp = propertyList.pop();
    const newState: object = { ...mainObject };
    const propertyTree =
        propertyList
            .reduce((obj, prop) => {
                obj[prop] = { ...newState[prop], ...obj[prop] };
                return obj[prop];
            }, newState);
    propertyTree[lastProp] = newValue;
    return newState as unknown;
}
这解决了我的问题。谢谢大家


这解决了我的问题。谢谢大家

您是否尝试过
let modified=JSON.parse(JSON.stringify(mainObject))
获取
mainObject
对象的新副本。如果这对您有好处,那么您可以执行
modified.firstLevel.secondLevel.thirdLevel.actualProperty=“New secret”。请注意,如果对象包含复杂的结构,例如
映射
集合
函数
等,那么
JSON.stringify()和
JSON.parse()
的组合将不起作用。您几乎已经描述了如何工作。但并不总是值得添加它。您是否尝试过
let modified=JSON.parse(JSON.stringify(mainObject))
获取
mainObject
对象的新副本。如果这对您有好处,那么您可以执行
modified.firstLevel.secondLevel.thirdLevel.actualProperty=“New secret”。请注意,如果对象包含复杂的结构,例如
映射
集合
函数
等,那么
JSON.stringify()和
JSON.parse()
的组合将不起作用。您几乎已经描述了如何工作。但并不是所有的事情都值得去做。