JS-对象属性不采用分配的值,而仅获取数组的最后一个值

时间:2019-12-06 00:36:57

标签: javascript arrays object

我有一个对象数组,每个对象都有一个ID列表,如下所示:

objects: [
    {
        ids: [1,2],
        name: 'alpha'
    },
    {
        ids: [2,3],
        name: 'bravo'
    }
]

我想将它们全部列出,例如对于每个单独的ID(即1、2或3),我在其ids属性中列出包含该ID的所有对象,然后创建一个名为{{1 }},让每个列出的对象都保存该id,就像这样:

id

但是,当我运行它时,所有列出的对象仅在其single id array: [1, 2, 3] id = 1 => [alpha (id = 1)] id = 2 => [alpha (id = 2), bravo (id = 2)] id = 3 => [bravo (id = 3)] 中获得最后一个ID,该ID仅是2或3,尽管我循环了单个id数组ids并分配了每个id

1, 2, 3

这里是一个示例:

single id array: [1, 2, 3]

id = 1 => [alpha (id = 2)]
id = 2 => [alpha (id = 2), bravo (id = 3)]
id = 3 => [bravo (id = 3)]
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    
    listData: [
    	{
      	ids: [1,2],
      	name: 'alpha'
      },
      {
      	ids: [1,2],
      	name: 'bravo'
      },
      {
      	ids: [1,2,3],
      	name: 'gamma'
      },
      {
      	ids: [3,4],
      	name: 'delta'
      }
    ],
    
    detailData: []
  },
  created() {
  	var ids = [];
    
    this.listData.forEach(data => {
    	data.ids.forEach(id => {
      	if(!ids.includes(id)) ids.push(id);
      })
    })
    
    ids.forEach(id => {
    	this.listData.forEach(data => {
      	if(data.ids.includes(id)) {
        	var obj = data;
          obj.id = id;
          this.detailData.push(obj);
        }
      })
    })
  }
})

JS Fiddle

我不知道为什么或如何发生。希望你们能找出问题并为我解释。非常感谢!

对不起,我的英语不好。

1 个答案:

答案 0 :(得分:1)

我认为您的问题是对象是通过引用传递的,当您将对象添加到detailData时,它是对该对象的引用,您稍后将对其进行更改。如果您在将对象添加到detailData之前复制该对象,我认为它将解决您的问题:

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    
    listData: [
    	{
      	ids: [1,2],
      	name: 'alpha'
      },
      {
      	ids: [1,2],
      	name: 'bravo'
      },
      {
      	ids: [1,2,3],
      	name: 'gamma'
      },
      {
      	ids: [3,4],
      	name: 'delta'
      }
    ],
    
    detailData: []
  },
  created() {
  	var ids = [];
    
    this.listData.forEach(data => {
    	data.ids.forEach(id => {
      	if(!ids.includes(id)) ids.push(id);
      })
    })
    
    ids.forEach(id => {
    	this.listData.forEach(data => {
      	if(data.ids.includes(id)) {
          var obj = data;
          obj.id = id;
          this.detailData.push({...obj}); // ... Makes a shallow copy of the object
        }
      })
    })
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(data, idx) in detailData">
        <td>{{ data.id }}</td>
        <td>{{ data.name }}</td>
        
      </tr>
    </tbody>
  </table>
</div>

注意:这只会创建一个浅表副本,这意味着如果您的ID位于嵌套对象中,则它将无效。参见此answer

如果您不想进行复制,则可以使用具有所需属性的对象来代替:

if(data.ids.includes(id)) {
    var obj = {id: id, name: data.name};
    this.detailData.push(obj);
}

如果您想要深层副本,也可以使用JSON:

if(data.ids.includes(id)) {
    var obj = JSON.parse(JSON.stringify(data));
    obj.id = id;
    this.detailData.push(obj);
}