使用JavaScript扩展运算符修改嵌套对象属性,有无更简便方法?
问题:简化嵌套JavaScript对象的属性修改
你有如下JavaScript对象:
const obj = { name: 'Jone', location: { presentAddress: { livingAddress: { City: {name: 'New York'}, Country: {name: 'USA'}, } } } }
想要将城市名称New York修改为London,尝试了如下代码(运行正常):
console.log({ ...obj, location:{ ...obj.location, presentAddress:{ ...obj.location.presentAddress, livingAddress: { ...obj.location.presentAddress.livingAddress, City:{ ...obj.location.presentAddress.livingAddress.City, name: "London" } } } } })
请问是否存在更简便的方式实现该修改?
更简便的实现方式
1. 直接修改原对象(允许修改原对象时首选)
如果不需要保留原对象的不可变性,直接逐层访问属性修改即可,这是最简洁的写法:
obj.location.presentAddress.livingAddress.City.name = 'London'; console.log(obj);
注意:这种方式会直接改变原对象的内容,若原对象需要保持不变则不适用。
2. 用Immer库简化不可变修改
如果要保持原对象不变,又不想写多层展开语法,Immer库的produce函数可以让你用“可变”的语法编写代码,最终自动生成新的不可变对象:
import { produce } from 'immer'; const newObj = produce(obj, draft => { draft.location.presentAddress.livingAddress.City.name = 'London'; }); console.log(newObj);
Immer会自动处理深层对象的拷贝逻辑,代码简洁易读,适合复杂嵌套的对象场景。
3. 自定义工具函数(无第三方库依赖)
如果不想引入第三方库,可以自己实现一个基于路径的深层修改函数,避免多层展开的冗余代码:
function deepUpdate(targetObj, pathStr, newValue) { // 先深拷贝原对象(这里用JSON方法,注意它的局限性) const newObj = JSON.parse(JSON.stringify(targetObj)); const keys = pathStr.split('.'); let current = newObj; // 逐层遍历路径,直到最后一个属性 for (let i = 0; i < keys.length - 1; i++) { current = current[keys[i]]; } // 修改目标属性 current[keys[keys.length - 1]] = newValue; return newObj; } const newObj = deepUpdate(obj, 'location.presentAddress.livingAddress.City.name', 'London'); console.log(newObj);
注意:JSON.parse(JSON.stringify())无法处理函数、Symbol、循环引用等特殊对象,若你的对象包含这些类型,需要完善深拷贝逻辑。
内容的提问来源于stack exchange,提问作者Abu Sayed
相关产品推荐
相关产品推荐

