JavaScript/Node.js中如何正确更新嵌套动态对象的属性值
问题根因与解决方案
根因说明
你遇到的问题核心是processObj()返回的mainObj中,所有一级属性(Test 1/2/3)指向的是同一个对象引用,而非三个独立的嵌套对象。你修改任意一个嵌套对象的属性,本质都是修改同一块内存地址的内容,因此最终所有属性都会被最后一次赋值的结果覆盖。
console.log可以正常输出对应值,是因为每次循环取到的x、y和count都是独立的栈变量,和堆内存中的对象引用无关。
验证方法
你可以先运行以下代码确认是否为引用问题:
const mainObj = await processObj() // 输出为true则确认是同一引用导致的问题 console.log(mainObj['Test 1'] === mainObj['Test 2'])
修复方案
方案1:调整processObj的生成逻辑(推荐)
大概率你当前的processObj是直接将同一个模板对象赋值给了所有Test X属性,调整为每次生成独立的嵌套对象即可:
// 错误写法示例(请勿使用) function processObj() { const template = { Nested1: 'value 1', Nested2: 'value 2', Nested3: 'value 3', Nested4: 'value 4', Nested5: 'value 5' } const res = {} for (let i = 1; i <=3; i++) { res[`Test ${i}`] = template // 直接赋值引用,所有Test X共用同一对象 } return res } // 正确写法示例 function processObj() { const res = {} for (let i = 1; i <=3; i++) { // 每次循环创建独立的嵌套对象 res[`Test ${i}`] = { Nested1: 'value 1', Nested2: 'value 2', Nested3: 'value 3', Nested4: 'value 4', Nested5: 'value 5' } // 若需要复用模板,可使用浅拷贝: // res[`Test ${i}`] = {...template} // 或 res[`Test ${i}`] = Object.assign({}, template) } return res }
方案2:无法修改processObj时的兼容处理
如果不能调整processObj的代码,可在拿到mainObj后先对每个嵌套对象做拷贝,再更新属性:
const mainObj = await processObj() for (const [key, nestedObj] of Object.entries(mainObj)) { // 拷贝嵌套对象,替换原引用 const newNested = {...nestedObj} mainObj[key] = newNested // 遍历更新属性 for (const [keyEm] of Object.entries(newNested)) { const count = await dbquery(key, keyEm) newNested[keyEm] = count } }
内容的提问来源于stack exchange,提问作者Geek65
相关产品推荐
相关产品推荐

