在循环中,我创建一个新变量,并在每次循环时(显然)设置一个新值
但是,当循环完成并且在循环之外时,我console.log()
将数组填充到循环中。它使用最后一个元素的值记录每个元素。
我尝试使用.push()
来填充数组。
state = {
dates: ['2019-02-04', '2019-02-05', '2019-02-06'],
entry: {
value1: undefined,
value2: undefined,
value3: {
value3_1: undefined,
value3_2: undefined
},
date: undefined
}
}
functionToFillArray() {
let entries = [],
entry = this.state.entry;
entry.value1 = 'value1';
entry.value2 = 'value2';
entry.value3 = {
value3_1: 'value3_1',
value3_2: 'value3_2'
};
this.state.dates.forEach((date, i) => {
entry.date = date;
entries.push(entry);
});
console.log(entries);
}
我期望的输出是:
[
{
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date: '2019-02-04'
},
{
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date: '2019-02-05'
},
{
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date: '2019-02-06'
}
]
我得到的值(总是相同的日期):
[
{
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date: '2019-02-06'
},
{
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date: '2019-02-06'
},
{
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date: '2019-02-06'
}
]
答案 0 :(得分:0)
您的代码在每次迭代中都会更改相同的this.state.entry
对象,并将该单个对象引用一次又一次地推送到数组,因此最后该数组确实包含多个条目,但是所有具有相同的对象引用。
总而言之,this.state.entry
值(您似乎想像模板一样使用)实际上没有任何作用。无论如何,您正在为其属性的 all 指定新值。因此,似乎没有必要。
只需替换一下:
let entry = this.state.entry;
具有:
let entry = {};
现在entry
将成为每次迭代中新创建的对象。
在对问题进行编辑之后,您一次又一次地为 same 对象分配一个date
属性。
原理保持不变。现在替换它:
functionToFillArray() {
let entries = [],
entry = this.state.entry;
entry.value1 = 'value1';
entry.value2 = 'value2';
entry.value3 = {
value3_1: 'value3_1',
value3_2: 'value3_2'
};
this.state.dates.forEach((date, i) => {
entry.date = date;
entries.push(entry);
});
console.log(entries);
}
...具有:
functionToFillArray() {
let entries = this.state.dates.map((date, i) => {
return {
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date
};
});
console.log(entries);
}
这样,您可以在每次迭代中创建一个新对象。首先初始化一个对象,然后覆盖它的每个属性是没有好处的,因为那时您仍在使用单个对象。每次迭代都需要一个新的。
请注意,数组的map
方法在这里比forEach
更有用,但与您的问题无关。
答案 1 :(得分:0)
使用解构。
const state = {
dates: ['2019-02-04', '2019-02-05', '2019-02-06'],
entry: {
value1: undefined,
value2: undefined,
value3: {
value3_1: undefined,
value3_2: undefined
},
date: undefined
}
};
function ToFillArray() {
let entries = [];
state.dates.forEach((date, i) => {
const entry = {
...state.entry,
value1: 'value1',
value2: 'value2',
value3: {
value3_1: 'value3_1',
value3_2: 'value3_2'
},
date
};
entries.push(entry);
});
console.log(entries);
}
ToFillArray();
答案 2 :(得分:0)
您不是要创建副本,而是要创建到this.state.entry的链接,然后再创建循环对象。 尝试先创建副本。
...
this.state.dates.forEach((date, i) => {
let entry = {...this.state.entry};
...
答案 3 :(得分:-1)
这是因为您总是引用相同的变量,而不是复制变量,修改状态,而是尝试以下操作:
let stateCopy= {...this.state};
let entry = stateCopy.entry
entry.value1 = 'value1';
entry.value2 = 'value2';
entry.value3 = {
value3_1: 'value3_1',
value3_2: 'value3_2'
};
entry.date = date;
entries.push(entry);
您可以参考this article以获得更详细的说明:)
在这种特殊情况下,由于您每次都分配属性,因此实际上并没有必要在状态下重用对象