使用push构建对象的JSON数组时发生意外行为

时间:2018-12-06 16:47:20

标签: javascript arrays json

尝试构建一个包含对象数组的简单JSON对象。

var forms = {};
var form = {};

forms.ID = 1;
forms.PackageName = "MyPackage";
forms.PackageForms = [];

form.Key = "0001XX";
form.Ordinal = 0;
forms.PackageForms.push(form);

form.Key = "0002XX";
form.Ordinal = 1;
forms.PackageForms.push(form);

但这会导致:

{"ID":1,"PackageName":"MyPackage","PackageForms":[{"Key":"0002XX","Ordinal":1},{"Key":"0002XX","Ordinal":1}]}

我知道为什么会这样:var'form'仍然指的是刚刚推送的对象。在不为每个项目创建不同对象的情况下,如何重用var'form'?这一定很简单,但是让我难以理解。

更新:

这似乎可行,看起来很干净

    var forms = {};
    forms.ID = 1;
    forms.PackageName = "MyPackage";
    forms.PackageForms = [];

    function Form(Key, Ordinal) {
        this.Key = Key;
        this.Ordinal = Ordinal;
    }

    forms.PackageForms.push(new Form("0001XX", 0));
    forms.PackageForms.push(new Form("0002XX", 1));

3 个答案:

答案 0 :(得分:1)

您可以每次创建一个新对象:

forms.PackageForms.push(form);
form = {};

或者您可以推送对象的副本:

forms.PackageForms.push(Object.assign({}, form));

答案 1 :(得分:0)

您观察到的结果是两种行为的组合:

  • array.push() 添加对输入对象的新引用。这意味着同一对象应多次包含在同一数组中。
  • 为对象的属性分配值意味着您正在更改该对象。

因此,您有:您将相同的对象多次添加到数组,并两次更改(覆盖)其属性。这就是为什么您在数组中两次发现同一对象,并且为它分配了最后一个值的原因。

更新

如果要将不同的对象存储到数组中,则每次必须实例化一个新对象(例如,使用new Object()),然后将值分配给其属性。

答案 2 :(得分:0)

在JavaScript中实现此目标的一种更典型的方法是根本不声明空对象({}),而使用object literal syntax

let forms = {
  ID: 1,
  PackageName: 'MyPackage',
  PackageForms: [
    {
      Key: '0001',
      Ordinal: 1
    },
    {
      Key: '0002',
      Ordinal: 2
    }
  ]
};

console.log(forms);


更新:来自OP的评论,这是我如何使用map的粗略概述:

let rawFormData = ...;  // From wherever; an array of objects

let packageForms = rawFormData.map(form => {
  // Any processing, local variables, etc required to derive `Key` and `Ordinal` from `form`

  return {
    Key: form.getKey(),          // Or whatever -
    Ordinal: form.getOrdinal()   //   these could be any expression
  };
});

let forms = {
  ID: 1,
  PackageName: 'MyPackage',
  PackageForms: packageForms
};