0

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

2
  • 1
    I would expect this(new bugObject(kddFlag)); to be the problem. Commented Jul 25, 2013 at 14:12
  • hi, thanks for replying, I refactored the code to post it here and put the wrong version, please have another look! Commented Jul 25, 2013 at 14:21

2 Answers 2

4

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)
            );
Sign up to request clarification or add additional context in comments.

1 Comment

hi, thank for answering, you mean I have to do something like var kddFlag and create a new kddFlag for each new object?
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.