更改数组中所有元素的属性值,但只需要一个

时间:2017-10-31 15:12:07

标签: javascript arrays

我创建了具有2个元素的users2数组。我想改变一个元素的属性值。输出应该是2 2 2 5,但它是2 2 5 5,所以我改变了数组中所有元素的属性值。

var users2 = [];
var fieldArray = [];
users2.push({"id": 0}, {"id": 1});
fieldArray.push([{text: "2"}, {text: "2"}, {text: "2"}]);
users2[0].arrShow = fieldArray;
users2[1].arrShow = fieldArray;

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

users2[1].arrShow[0][0].text = "5";

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

2 个答案:

答案 0 :(得分:3)

您的两个用户对象都使用相同 arrShow(也可通过fieldArray访问),因此使用相同 0th输入该数组中的第0个条目。当然,无论您查看该对象的路径如何,都会反映更改该对象的状态。

相反,请为您的用户单独 arrShow添加单独的对象:



var users2 = [
  {
    id: 0,
    arrShow: [
      [{text: "2"}, {text: "2"}, {text: "2"}]
    ]
  },
  {
    id: 1,
    arrShow: [
      [{text: "2"}, {text: "2"}, {text: "2"}]
    ]
  }
];

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

users2[1].arrShow[0][0].text = "5";

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);




或者在初始化后单独进行:



var users2 = [
  {id: 0, arrShow: []},
  {id: 1, arrShow: []}
];
users2[0].arrShow.push(
  [{text: "2"}, {text: "2"}, {text: "2"}]
);
users2[1].arrShow.push(
  [{text: "2"}, {text: "2"}, {text: "2"}]
);

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

users2[1].arrShow[0][0].text = "5";

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);




或者,如果您需要将arrShow基于单独的fieldArray,则需要同时复制fieldArray及其中的对象;您可以使用Array#mapObject.assign(这是新的,但很容易在旧环境中填充)来实现这一点:



var users2 = [
  {id: 0, arrShow: []},
  {id: 1, arrShow: []}
];
var fieldArray = [{text: "2"}, {text: "2"}, {text: "2"}];

users2.forEach(function(user) {
  user.arrShow.push(
    fieldArray.map(function(entry) {
      return Object.assign({}, entry);
    })
  );
});

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

users2[1].arrShow[0][0].text = "5";

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);




答案 1 :(得分:1)

您可能希望避免重复代码,并假设分配将隐式为您创建深层副本。那不是发生了什么。

要创建标准对象结构,请创建一个返回一组全新对象的函数。

function makeUser(id) {
  return {
    id: id,
    arrShow: [
      [{text: "2"}, {text: "2"}, {text: "2"}]
    ]
  };
}

然后在需要一组新数据时调用它。

var users2 = [
  makeUser(0),
  makeUser(1),
];

现在,改变一个用户的数据将不再影响另一个用户的数据。

这是一个演示:



var users2 = [
  makeUser(0),
  makeUser(1),
];

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

users2[1].arrShow[0][0].text = "5";

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

function makeUser(id) {
  return {
    id: id,
    arrShow: [
      [{text: "2"}, {text: "2"}, {text: "2"}]
    ]
  };
}




这也可以使用构造函数或ES6 class语法来完成。



class User {
  constructor(id) {
    this.id = id;
    this.arrShow = [
      [{text: "2"}, {text: "2"}, {text: "2"}]
    ];
  }
}

var users2 = [
  new User(0),
  new User(1),
];

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);

users2[1].arrShow[0][0].text = "5";

console.log(users2[0].arrShow[0][0].text);
console.log(users2[1].arrShow[0][0].text);