无法在forEach中分配适当的数组值

时间:2019-05-03 15:46:27

标签: javascript arrays foreach

我最近有一种奇怪的行为(对我来说)。

 let test = [
    { id: 1, name: 'test1' },
    { id: 2, name: 'test2' },
    { id: 3, name: 'test3' }
]
let test2 = []
test.forEach((elem, index) => {

    console.warn(elem, index);
    test2.push(elem.name)
    elem.arr = test2
})

console.warn(test);

我希望预期的结果是这样

[ { id: 1, name: 'test1', arr: [ 'test1'] },
  { id: 2, name: 'test2', arr: [ 'test1', 'test2'] },
  { id: 3, name: 'test3', arr: [ 'test1', 'test2', 'test3' ] }]

但是我明白了

[ { id: 1, name: 'test1', arr: [ 'test1', 'test2', 'test3'] },
  { id: 2, name: 'test2', arr: [ 'test1', 'test2', 'test3'] },
  { id: 3, name: 'test3', arr: [ 'test1', 'test2', 'test3'] }]

有人可以解释我为什么会发生这种情况(可能是关于引用的事吗?)和解决方案?

3 个答案:

答案 0 :(得分:3)

只有一个test2数组,该数组连续三次(通过arr)被引用。所有这些条目都指向一个单个数组。

您可能想复制一份:

elem.arr = [...test2]

let test = [
    { id: 1, name: 'test1' },
    { id: 2, name: 'test2' },
    { id: 3, name: 'test3' }
]
let test2 = []
test.forEach((elem, index) => {

    //console.log(elem, index);
    test2.push(elem.name)
    elem.arr = [...test2]
})

console.log(JSON.stringify(test, null, 2));

答案 1 :(得分:1)

我相信正在发生的事情是,每个元素的arr属性被设置为等于test2引用,而不是在那个时候复制test2的内容。

此处有更多信息:Is JavaScript a pass-by-reference or pass-by-value language?

另请参阅:Copy array by value

基于第二个链接,在分配给elem.arr时需要创建新的数组。

elem.arr = test2.slice();

[更新] @spender有一种更新的方式可以复制我不知道的数组(仍然赶上ES6)。另请参阅:https://www.samanthaming.com/tidbits/35-es6-way-to-clone-an-array

答案 2 :(得分:1)

  

大概是关于引用的?

您是正确的。该分配不会将test2的值复制到elem.arr中 因此,在操作完成之后。如果您尝试运行test2 = [] 所有arr属性将是[]

如果您愿意的话,您可以像花费者的答案那样破坏结构