关于javascript:我可以拥有两个具有相同属性名称的对象吗?

can i have two objects with the same property names?

每当我试图更改数组y中的第一个对象时,数组中的所有其他对象y属性也会更改,是否有任何方法可以防止这种情况发生,或者有一种方法可以将多个对象添加到共享相同属性的数组中?我一直在尝试解决这个问题(我正在创建一个游戏,使用类似的数组进行子弹射击,每当我更改数组中第一个项目的y属性时,数组中的所有其他y属性都会随之更改),我想这可能是个问题吗?

1
2
3
4
5
6
7
var obj = {x:30,y:20};
var arr = [];
for(var i = 0;i<3;i++) {
arr.push(obj);
}
arr[0].y = 40;
document.write(arr[0].y +"" + arr[1].y);


您可以通过在.push()中定义一个对象来解决这个问题。

这将为数组的每个元素创建一个新对象,而不是包含对同一对象的多个引用的数组。

1
2
3
4
5
6
var arr = [];
for(var i = 0;i<3;i++) {
arr.push({x:30, y:20});
}
arr[0].y = 40;
document.write(arr[0].y +"" + arr[1].y);

在JavaScript中,对象作为指向对象内部值的指针存储在内存中。这与原始数据类型(intchar等)的方式不同。

显示这一点的一个好方法是尝试打印出对象,而不是打印出一个int:HTML:

1
 

JS:

1
2
3
4
var x = 5;
var obj = {x:30,y:20};
document.getElementById("anelementhere").innerHTML = x;
document.getElementById("anotherelementhere").innerHTML = obj;

jspiddle:https://jsfiddle.net/d3ohpqqpqpqp/

你应该能够看到类似于:

1
2
5
[object Object]

现在知道了,数组中存储的不是{{x:30, y:20}, {x:30, y:20}, {x:30, y:20}},而是{[object Object], [object Object], [object Object]},它们都指向一个{x:30, y:20}。这就是所有y属性在改变一个属性后发生变化的原因。现在,一个简单的解决方案,如@irkenvader所示,是在将对象放入数组时对其进行初始化的地方。但是,如果出于某种原因仍希望原始对象位于数组之外,则这是另一种解决方案:

1
2
3
4
5
6
7
var obj = {x:30,y:20};
var arr = [];
for(var i = 0;i<3;i++) {
    arr.push({x:obj.x, y:obj.y});
}
arr[0].y = 40;
document.write(arr[0].y +"" + arr[1].y);

jfiddle:https://jsfiddle.net/9gzyr38x/


除了@irken侵略者给出的答案,您还可以使用jquery非常容易地执行对象的深度复制:

1
2
3
4
5
6
7
8
var obj = {x: 30, y: 20};
var arr = [];
for(var i  = 0; i < 3; i++) {
  arr.push(jQuery.extend(true, {}, obj));
}

arr[0].y = 40;
document.write(arr[0].y +"" + arr[1].y);

您正在生成单个obj,并在数组中传递对同一对象的引用4次

相反,您可以尝试在每次迭代中创建新对象:

1
2
3
4
5
6
var arr = [];
for(var i = 0;i<3;i++) {
  arr.push({x:30,y:20});
}
arr[0].y = 40;
document.write(arr[0].y +"" + arr[1].y);

您还可以查找"克隆"对象的各种方法。Angular、JQuery和下划线都提供了这样做的方法,或者您可以查看如何克隆JS对象?