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

您好,我有一个模板对象,如下所示:


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 创建新的对象行。谁能发现我犯的错误。


qq_花开花谢_0
浏览 113回答 2
2回答

慕的地6264312

你必须小心改变你的对象。最好深度克隆您的对象和数组。这是编写代码的另一种方法:const allData = [];for (let i = 0; i < allDetails.length; i++) {&nbsp; &nbsp; const detail = allDetails[i];&nbsp; &nbsp; const cells = [];&nbsp; &nbsp; for (let j = 0; j < baseObj.cells.length; j++) {&nbsp; &nbsp; &nbsp; &nbsp; const cell = {...baseObj.cells[j]};&nbsp; &nbsp; &nbsp; &nbsp; switch (cell.key) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'id':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell.value = detail.id;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'name':&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cell.value = detail.name;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; cells.push(cell)&nbsp; &nbsp; }&nbsp; &nbsp; const row = {objKey: detail.objKey, index: i + 1, cells};&nbsp; &nbsp; allData.push(row);}

ibeautiful

您的问题在于:row.cells = Object.assign([], baseObj.cells);这会对数组进行浅表复制,这意味着其中的对象baseObj不会被复制,并且在每次迭代时都引用相同的对象引用。您可以通过克隆对象来解决此问题,这可以通过使用以下方法来实现:row.cells = baseObj.cells.map(o => ({...o}));你也在设置row.key = detail.objKey,当这确实应该是row.objectKey = detail.objKey请参阅下面的示例:const baseObj = {&nbsp; objKey: '',&nbsp; index: 1,&nbsp; cells: [{&nbsp; &nbsp; &nbsp; key: 'id',&nbsp; &nbsp; &nbsp; value: ''&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; key: 'name',&nbsp; &nbsp; &nbsp; value: ''&nbsp; &nbsp; }&nbsp; ]};const allDetails = [{&nbsp; &nbsp; objKey: '876',&nbsp; &nbsp; name: 'abc',&nbsp; &nbsp; id: '123',&nbsp; &nbsp; address: '123abc'&nbsp; },&nbsp; {&nbsp; &nbsp; objKey: '098',&nbsp; &nbsp; name: 'def',&nbsp; &nbsp; id: '456',&nbsp; &nbsp; address: '456def'&nbsp; },];const allData = [];for (let i = 0; i < allDetails.length; i++) {&nbsp; const detail = allDetails[i];&nbsp; const row = Object.assign({}, baseObj);&nbsp; row.cells = baseObj.cells.map(o => ({...o}));&nbsp; row.objKey = detail.objKey;&nbsp; row.index = i + 1;&nbsp; for (let j = 0; j < row.cells.length; j++) {&nbsp; &nbsp; const cell = row.cells[j];&nbsp; &nbsp; switch (cell.key) {&nbsp; &nbsp; &nbsp; case 'id':&nbsp; &nbsp; &nbsp; &nbsp; cell.value = detail.id;&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; case 'name':&nbsp; &nbsp; &nbsp; &nbsp; cell.value = detail.name;&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; }&nbsp; }&nbsp; 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) => ({&nbsp; ...baseObj,&nbsp;&nbsp; objKey,&nbsp;&nbsp; index: index+1,&nbsp;&nbsp; cells: baseObj.cells.map(o => ({...o, value: r[o.key]}))}));console.log(result);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript