代码之家  ›  专栏  ›  技术社区  ›  m51

使用循环向数组填充对象

  •  0
  • m51  · 技术社区  · 7 年前

    我需要创建一个充满对象的数组。让我们说 { foo: 0} 。然后我想添加属性 bar 对每个具有不同值的对象。例如:值=数组中项目的索引。

    看起来像这样

    const table = new Array(10).fill({foo: 0});
    
    for (let i = 0; i < table.length; i += 1) {
        table[i].bar = i;
    }
    

    我期望得到的是:

    [
        { foo: 0, bar: 0 },
        { foo: 0, bar: 1 },
        { foo: 0, bar: 2 },
        ...
        { foo: 0, bar: 9 }
    ]
    

    我得到了什么:

    [
        { foo: 0, bar: 9 },
        { foo: 0, bar: 9 },
        { foo: 0, bar: 9 },
        ...
        { foo: 0, bar: 9 }
    ]
    

    为什么会这样?我哪里出错了?

    DEMO

    编辑 澄清

    我不想用像这样的新对象替换数组中的对象 table[i] = {foo: 0, bar: i} 我只想向现有对象添加属性。

    3 回复  |  直到 7 年前
        1
  •  1
  •   Leonid Pyrlia    7 年前

    Array.fill() 获取一个值并用它填充数组。 由于非基元(对象、数组)是通过引用传递的,因此对任何项的修改都将导致其余项也发生更改。

    相反,您可以使用 Array.from() 并将对象传递给它的映射函数:

    const table = Array.from({length:10}, _ => ({foo:0}));
    
    for (let i = 0; i < table.length; i += 1) {
        table[i].bar = i;
    }
    
    console.log(table);
        2
  •  4
  •   Eric Yang    7 年前

    您的数组中有一个对单个对象的引用。所以现在发生的是,你正在更新同一个底层对象。如果您熟悉C,就好像有N个指针指向同一个底层对象。无论操作哪个N指针,都将更改基础对象。

    const table = new Array(10)
    
    for (let i = 0; i < table.length; i += 1) {
       table[i] = {foo: 0, bar: i}
    }
    

    这将为数组中的每个条目创建一个新对象

        3
  •  1
  •   BlackBeard    7 年前

    imho,你在找这样的东西:

    const table = new Array(10);
    
    for (let i = 0; i < table.length; i += 1) {
        table[i] = {'foo': 0, 'bar': i};
    }
    
    console.log(table)

    一个线性解决方案使用 ECMAScript-6 :

    const table = Array.from(new Array(10).keys()).map(e => ({'foo': 0, 'bar': e}))
    
    console.log(table)