为了账号安全,请及时绑定邮箱和手机立即绑定

在 javascript 中动态创建新对象时,常量 JSON 对象值在循环中发生变化

在 javascript 中动态创建新对象时,常量 JSON 对象值在循环中发生变化

qq_花开花谢_0 2023-09-28 16:05:49
您好,我有一个模板对象,如下所示:const baseObj = {  objKey: '',  index: 1,  cells: [    {      key: 'id',      value: ''    },    {      key: 'name',      value: ''    }  ]};我想从数组创建对象的动态数组,如下所示:const allDetails = [  {    objKey: '876',    name: 'abc',    id: '123',    address: '123abc'  },  {    objKey: '098',    name: 'def',    id: '456',    address: '456def'  },]为此,我编写了一个简单的循环,如下所示:const allData = [];for(let i = 0; i < allDetails.length; i++){  const detail = allDetails[i];  const row = Object.assign({}, baseObj);  row.cells = Object.assign([], baseObj.cells);  row.key = details.objKey;  row.index = i+1;  for(let j = 0; j < row.cells.length; j++)  {    const cell = row.cells[j];    switch(cell.key){      case 'id': {        cell.value = detail.id;        break;      }      case 'name': {        cell.value = detail.name;        break;      }    }  }  allData.push(row);}现在我期望 allData 为:[  {    objKey: '876',    index: 1,    cells: [      {        key: 'id',        value: '123'      },      {        key: 'name',        value: 'abc'      }    ]  },  {    objKey: '098',    index: 2,    cells: [      {        key: 'id',        value: '456'      },      {        key: 'name',        value: 'def'      }    ]  }]但当我打印时,它给我的是:[  {    objKey: '876',    index: 1,    cells: [      {        key: 'id',        value: '456'      },      {        key: 'name',        value: 'def'      }    ]  },  {    objKey: '098',    index: 2,    cells: [      {        key: 'id',        value: '456'      },      {        key: 'name',        value: 'def'      }    ]  }]看起来数组值每次都被覆盖。在调试时,我可以在更改行单元格的值时以某种方式看到它也在更改 baseObj 单元格的值。然而,只有对象数组出现问题。我看不出哪里出了问题,因为在每个循环中我都从 baseObj 创建新的对象行。谁能发现我犯的错误。
查看完整描述

2 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

你必须小心改变你的对象。最好深度克隆您的对象和数组。


这是编写代码的另一种方法:


const allData = [];

for (let i = 0; i < allDetails.length; i++) {

    const detail = allDetails[i];

    const cells = [];

    for (let j = 0; j < baseObj.cells.length; j++) {

        const cell = {...baseObj.cells[j]};

        switch (cell.key) {

            case 'id':

                cell.value = detail.id;

                break;

            case 'name':

                cell.value = detail.name;

                break;

        }

        cells.push(cell)

    }

    const row = {objKey: detail.objKey, index: i + 1, cells};

    allData.push(row);

}


查看完整回答
反对 回复 2023-09-28
?
ibeautiful

TA贡献1993条经验 获得超5个赞

您的问题在于:


row.cells = Object.assign([], baseObj.cells);

这会对数组进行浅表复制,这意味着其中的对象baseObj不会被复制,并且在每次迭代时都引用相同的对象引用。您可以通过克隆对象来解决此问题,这可以通过使用以下方法来实现:


row.cells = baseObj.cells.map(o => ({...o}));

你也在设置row.key = detail.objKey,当这确实应该是row.objectKey = detail.objKey


请参阅下面的示例:


const baseObj = {

  objKey: '',

  index: 1,

  cells: [{

      key: 'id',

      value: ''

    },

    {

      key: 'name',

      value: ''

    }

  ]

};


const allDetails = [{

    objKey: '876',

    name: 'abc',

    id: '123',

    address: '123abc'

  },

  {

    objKey: '098',

    name: 'def',

    id: '456',

    address: '456def'

  },

];


const allData = [];

for (let i = 0; i < allDetails.length; i++) {

  const detail = allDetails[i];

  const row = Object.assign({}, baseObj);

  row.cells = baseObj.cells.map(o => ({...o}));

  row.objKey = detail.objKey;

  row.index = i + 1;

  for (let j = 0; j < row.cells.length; j++) {

    const cell = row.cells[j];

    switch (cell.key) {

      case 'id':

        cell.value = detail.id;

        break;

      case 'name':

        cell.value = detail.name;

        break;

    }

  }

  allData.push(row);

};


console.log(allData);


上述问题的另一种解决方案是使用.map()构建一个新对象,我们从基础对象中获取/借用属性,并将任何重叠的属性替换为当前迭代对象中的属性:


const baseObj = { objKey: '', index: 1, cells: [ { key: 'id', value: '' }, { key: 'name', value: '' } ] }; const allDetails = [ { objKey: '876', name: 'abc', id: '123', address: '123abc' }, { objKey: '098', name: 'def', id: '456', address: '456def' }, ];


const result = allDetails.map(({objKey, address, ...r}, index) => ({

  ...baseObj, 

  objKey, 

  index: index+1, 

  cells: baseObj.cells.map(o => ({...o, value: r[o.key]}))

}));


console.log(result);


查看完整回答
反对 回复 2023-09-28
  • 2 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信