Reputation: 14689
I have an object which have an array to hold all the children of this object, the children are also instances of the same object (I need this for a tree like structure where the object is a node of the tree)
var bugObject = function(kFlag){
this._kFlag = kFlag;
this._children = []
}
bugObject.prototype.getKFlag = function(){
return this._kFlag;
};
bugObject.prototype.setChildrenFromData = function(data){
var i = 0;
var kFlag = {flagType : 'someFlag', flagValue : -1};
kddFlag.flagType = data.flagType;
var len = data.flagValues.length;
for( i = 0 ; i < len ; i++){
kFlag.flagValue = data.flagValues[i];
this._children.push(
new bugObject(kFlag)
);
//this is just to print the children
for(j = 0; j<=i; j++){
console.log('child : ' + j + ' for test :' + i);
console.log(this._children[i].getKFlag());
}
console.log('--------------------');
}
};
The idea is to create the children of this object based on some data using the setChildrenFromData method here is how I am doing this:
function main(){
console.log('main is called');
var data = {"flagType":"someFlag","flagValues":[0,0,0,0,0,0,0,0,1,0,0]};
var rootNode = new bugObject(null);
rootNode.setChildrenFromData(data);
}
main();
The problem is that instead of getting 11 objects each of them have one of these flags [0,0,0,0,0,0,0,0,0,0,1] I get 11 objects all of them have the flag 1, (the last one)!
Could you please see what is wrong!
Thanks
Upvotes: 0
Views: 563
Reputation: 27423
This is a problem with assigning references to objects, and is well known, and even happens in other languages.
I'll give you a simpler example:
Let's say you want a 3x3 matrix, modelled as an array of arrays, filled with rows that are all zeros.
You might be tempted to write.
row = [0,0,0];
A = [];
for(j=0;j<3;++j) A[j] = row;
But then if you change A[0][0] = 10;
And you look in A[1][0]
, you get 10
, not 0
.
This is because there is only one row
, and all of the elements of A
are assigned to it.
To correct this pattern in Javascript, the object needs to be a new object each time. This
can be done with a literal A[j]=[0,0,0]
or it can be A[j]=row.slice()
which makes a shallow copy that solves the problem for one level, or a deep copy.
Upvotes: 2
Reputation: 48972
The problem is this:
for( i = 0 ; i < len ; i++){
kddFlag.flagValue = data.flagValues[i];
this._children.push(
new bugObject(kddFlag)
);
you're creating 11 bugObject
. But all of them have this._kddFlag
pointing to the same kddFlag
object, at the end of the loop kddFlag.flagValue
is 1. To fix this, move your code into the loop. Like this:
for( i = 0 ; i < len ; i++){
var kddFlag = {flagType : 'outlier', flagValue : -1};
kddFlag.flagType = data.flagType;
kddFlag.flagValue = data.flagValues[i];
this._children.push(
new bugObject(kddFlag)
);
Upvotes: 4