如何解决在JSON文件中创建新对象的问题?

时间:2019-08-30 22:21:00

标签: javascript node.js json

我正在尝试创建一个函数,该函数在调用时将更新json文件中的特定对象。但是,它会更新对象并创建一个新对象。

我尝试了许多不同的方法来使它起作用,但是都失败了。我最接近它的是下面显示的代码,但是它仍然不能满足要求。

这是我的功能:

var fs = require('fs');
var _ = require("underscore");

module.exports = {
  personalUpdate: function (id, forename, surname, dob, gender, callback) {    
    let rawdata = fs.readFileSync('data.json');
    let data = JSON.parse(rawdata);
    let filtered = _.where(data['students'], { id: id });
    let all = filtered[0];

    all.forename = forename;
    all.surname = surname;
    all.dob = dob;
    all.gender = gender;

    data["students"].push(all);

    fs.writeFileSync('data.json', JSON.stringify(data, null, 2), (err) => {
      if (err) throw err;
    });
    callback("success");

  }
}

这是我要更新的JSON文件:

{
  "teachers": [
    {
      "name": "",
      "email": "",
      "password": "",
      "formGroup": "",
      "id": ""
    }
  ],
  "students": [
    {
      "surname": "test",
      "forename": "test",
      "dob": "",
      "homeAddress": "",
      "homePhone": "",
      "gender": "",
      "tutorGroup": "",
      "schoolEmail": "",
      "grades": [
        {
          "french": 8,
          "maths": 7
        }
      ],
      "id": ""
    },
    {
      "surname": "test2",
      "forename": "test2",
      "dob": "",
      "homeAddress": "test2",
      "homePhone": "",
      "gender": "",
      "tutorGroup": "",
      "schoolEmail": "",
      "grades": [
        {
          "french": 9,
          "maths": 8
        }
      ],
      "id": ""
    }

  ]
}

我必须删除并更改其中的对象和信息,因为其中包含机密信息。

运行此函数时,它将查找参数中指定的对象。然后,它更新该对象,但随后在原始JSON对象的底部创建了另一个对象,这是不应该的。

还有,还有更好的方法来更新JSON文件中的特定对象吗?

1 个答案:

答案 0 :(得分:1)

tl; dr

  1. 结果集重复,因为您将其推入数组
  2. 之所以应用此更改,是因为这些变量拥有相同的对象引用,因此它们在共享相同指针的对象之间被镜像。

说明

由于data["students"].push(all);指令,它会创建一个新的。

当您使用javascript操作对象时,您需要了解它们之间的引用是如何工作的,这样就可以避免bug并从中受益。

例如,按照以下说明进行操作:

let a = {"x": 1};
let b = a;
b.x = 3;
console.log(a) // it will output {"x": 3}

请注意,我们:

  1. 创建一个属性x等于1的对象,并将其分配给变量a
  2. 初始化值为b的变量a
  3. 更改变量/对象x上的属性b
  4. 然后,我们可以发现由于对象引用,更改也反映在变量a中。

因此,基本上,这完全是您执行指令all.forename = forename;时所发生的事情,它更改了变量all,而且更改了其派生的原始对象。

Here is a nice reference对该概念进行了更深入的解释

@EDIT

我强烈建议您不要使用sync之类的函数readFileSync,因为这会阻塞事件循环。 Here is the official guidelines about it