Reputation: 179
have such type of object. Creating elemens in FabricJS canvas and setting attributes:
canvas.forEachObject(function (e) {
e.hasControls = e.hasBorders = false; //remove borders/controls
e.isStatic = true;
e.corners = [false, false, false, false, false];
});
fitElement.destination.corners[1] = true;
fitElement.origin.corners[3] = true;
console.log(fitElement.destination.corners);
console.log(fitElement.origin.corners);
And the result is
[false, true, false, true, false]
[false, true, false, true, false]
Why changing one array in object causes the chages of another? What I am doing wrong? Thanks
Upvotes: 0
Views: 87
Reputation: 48247
JavaScript variables for the vast majority of objects are references, which leads to issues like this. Somewhere in your code, you almost certainly do the equivalent of destination.corners = foo; ... origin.corners = foo;
and end up using the same array for both.
You can test this easily enough by asking if fitElement.destination.corners === fitElement.origin.corners
after assigning. The ===
(strict equality) operator check if both variables reference the same object. In this case, I'll bet they do and that's the source of your problem.
The most common way of accidentally doing that -- in my experience -- is passing a parent object or taking a property from one or more objects that happen to point to the same array. For example, doing:
var foo = {bar: [1, 2, 3]};
var baz = _.extend({}, foo); // create a "copy"
foo.bar[1] = 9;
console.log(baz.bar);
While the parent object (foo
-> baz
) is cloned and foo !== baz
, the child (bar
) is not and any changes to foo.bar
will also affect baz.bar
.
Libraries that offer a copy/clone/extend function may also provide a deep clone that will walk down the object and clone any children as well (for example, lodash provides clone and cloneDeep.
In your case, since you're using the arrays individually, I would suggest making a copy of each just before assigning them to the corners. You can copy an array with slice
:
var defaultCorners = [false,false,false,false,false];
var destCorners = defaultCorners.slice();
var originCorners = defaultCorners.slice();
fitElement.destination.corners = destCorners;
fitElement.origin.corners = originCorners;
destCorners[1] = true;
originCorners[3] = true;
console.log(fitElement.destination.corners);
console.log(fitElement.origin.corners);
This will avoid the problem, but remember: slice
makes another shallow copy, so any objects within the array will have this same issue.
Upvotes: 1
Reputation: 11597
There's only one explanation: fitElement.destination.corners
and fitElement.origin.corners
are the very same array.
Somewhere up in the your code you assign one array or object to the other, so you are referencing the same data in memory, for example:
var vector5 = new Vector5(); // of my invention, just to explain the concept
fitElement.origin.corners = vector5;
fitElement.destination.corners = vector5;
Or:
fitElement.origin.corners = vector5;
fitElement.destination.corners = fitElement.origin.corners;
Or a step up in the nesting:
fitElement.origin.corners = vector5;
fitElement.destination = fitElement.origin;
Upvotes: 1