Javascript 更改对象';的属性也会影响另一个对象

Javascript 更改对象';的属性也会影响另一个对象,javascript,jquery,html,canvas,kineticjs,Javascript,Jquery,Html,Canvas,Kineticjs,问题:当我更改一个多边形的点poly2时,它也会更改另一个多边形的点 为什么改变一个也会改变另一个,我们如何将它们解耦 console.log(poly.getPoints()[1].x); // 100 // Make a change to `poly2` poly2.setPoints(poly.getPoints()); poly2.getPoints()[1].x=200 console.log(poly.getPoints()[1].x); // 200 (both poly

问题:当我更改一个多边形的
poly2
时,它也会更改另一个多边形的

为什么改变一个也会改变另一个,我们如何将它们解耦

console.log(poly.getPoints()[1].x);  // 100

// Make a change to `poly2`
poly2.setPoints(poly.getPoints());
poly2.getPoints()[1].x=200

console.log(poly.getPoints()[1].x);  // 200 (both poly and poly2 are affected!)

jsiddle:

执行此操作时,多边形和多边形2对象正在引用相同的点数组:

poly2.setPoints(poly.getPoints());
将其更改为:

poly2.setPoints([0, 0, 100, 0, 100, 100, 0, 100]);
这是你的问题。点阵列是同一个对象

因为您的数组中有数组,所以
切片(0)
技巧将不起作用,您需要深度复制

幸运的是,您使用的是jQuery,它有一个方法来实现这一点

将上述行替换为:

poly2.setPoints($.extend(true, [], poly.getPoints()));

要克隆点,而不是在多边形之间共享点,您需要自己为每个点创建新对象

您可以通过以下方式执行此操作:

或:


在评估问题时,其他答案都是正确的,但还有另一种解决方法:在设置点阵列时“克隆”点阵列。换言之:

poly2.setPoints(poly.getPoints().slice());

如果出于某种原因
getPoints()
返回的不是数组,那么您将需要一种不同的克隆方法(例如axel.michel建议的方法),但因为我认为这种方法确实适用于您。

问题是,poly.getPoints是一组动态指针对象,要摆脱它,请尝试以下方法:

poly2.setPoints(JSON.parse(JSON.stringify(poly.getPoints())));

请在帖子中包含代码。我需要通过将
poly.setPoints()
数组传递到
poly.getPoints()
来设置
poly2
。这听起来可能很简单,但我怎么做呢?调用poly.getPoints().slice()获取数组的副本(而不是数组引用的副本)
slice
不起作用,因为它太浅-
getPoints()
返回一个对象数组,而不是原始数组。
console.log(poly.getPoints())
在Chrome开发工具中告诉我它是一个数组,返回
[0,01000,01000]
!那么Chrome错了?它是一个数组。正如我在其他地方注意到的,
.slice()
不起作用,因为它是一个两层深的数组-
.slice()
只执行浅层复制,但仍将共享保存单个坐标的小型对象。@Nyxynyx:这是我得到的:
[{“x”:0,“y”:0},{“x”:100,“y”:0},{“x”:100,“y”:100}{“x”:0,“y”:100}]
。我没有像你说的那样得到平面数组。你能再检查一下吗?是的,我得到的和你一样。我猜数组中的对象的行为方式与你在回答的评论中解释的相同。我需要了解一些事情,出于某种奇怪的原因,我在做了javascript/jquery/backbone/nodejs之后没有遇到这个问题我的时间…首先,快速术语点:这是一个“单位”“数组,因为它不包含任何子数组。但是,它确实包含对象,而这些对象在克隆阵列时不会被克隆,因此必须手动克隆它们。其他回答者提供了其他替代方案,像jQuery和下划线这样的主要库也有可以使用的克隆方法。我们更愿意说它返回一个对象引用,因为JavaScript没有指针作为可以操作的基本类型。但所有对象的行为都是这样的。考虑:
a={};b=a;a、 x=3;console.log(b.x)
将打印3-因为
b=a
使
b
引用了
a
引用的同一对象。
poly2.setPoints($.map(poly.getPoints(), function (p) {
    return { x: p.x, y: p.y };
}));
poly2.setPoints(poly.getPoints().slice());
poly2.setPoints(JSON.parse(JSON.stringify(poly.getPoints())));