我可以有两个具有相同属性名称的对象吗? [复制]

Posted

技术标签:

【中文标题】我可以有两个具有相同属性名称的对象吗? [复制]【英文标题】:can i have two objects with the same property names? [duplicate] 【发布时间】:2016-04-04 21:24:42 【问题描述】:

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

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);

【问题讨论】:

数组中的每个索引都包含对同一对象的引用 - 因此更改一个索引中的值将对所有索引生效。 【参考方案1】:

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

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

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);

【讨论】:

【参考方案2】:

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

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

<div id="anelementhere"></div>
<div id="anotherelementhere"></div>

JS:

var x = 5;
var obj = x:30,y:20;
document.getElementById("anelementhere").innerhtml = x;
document.getElementById("anotherelementhere").innerHTML = obj;

JSFiddle:https://jsfiddle.net/d3ohpqqp/

您应该能够看到类似于:

5
[object Object]

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

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);

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

【讨论】:

【参考方案3】:

您正在创建一个 obj 并在您的数组中传递对同一对象的引用 4 次

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

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 和 underscore 都提供了这样做的方法,或者你可以查看How to clone js object?

【讨论】:

3 次* - 我敢肯定这就是你的意思 :) @Plato:很酷,但 IrkenInvader 用第一个建议击败了你 2 分钟。 啊,是的,我个人尝试总是在 for 循环中使用 【参考方案4】:

除了@IrkenInvader 给出的答案,你还可以使用jQuery to very easily perform a deep-copy 对象:

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);

【讨论】:

以上是关于我可以有两个具有相同属性名称的对象吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

我可以拥有两个具有不同捆绑 ID 和相同名称的应用程序吗?

BigTable:来自不同列族的两个列限定符可以具有相同的名称吗?

有没有办法合并两个具有相同键的 JS 对象? [复制]

Linq 确保没有两个对象具有相同的属性值

C#利用反射实现两个类的对象之间相同属性的值的复制

我可以提交具有相同 Icon.png 但不同包名称的 iPhone 应用程序吗