JavaScript:赋值给数组中的对象会更改数组中所有对象的值

时间:2013-07-25 14:03:39

标签: javascript javascript-objects

我有一个对象,它有一个数组来保存这个对象的所有子节点,子节点也是同一个对象的实例(我需要这个树,就像树一样的结构,其中对象是树的节点)

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('--------------------');
 }

}; 

我们的想法是使用setChildrenFromData方法基于某些数据创建此对象的子对象 这是我如何做到这一点:

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

问题是,不是得到11个对象,而是每个对象都有这些标志之一[0,0,0,0,0,0,0,0,0,0,1]我得到了11个对象有旗1,(最后一个)!

你可以看看有什么问题!

谢谢

2 个答案:

答案 0 :(得分:4)

问题在于:

for( i = 0 ; i < len ; i++){
        kddFlag.flagValue = data.flagValues[i];
        this._children.push(
            new bugObject(kddFlag)
        );

你正在创建11 bugObject。但是所有这些都有this._kddFlag指向同一个kddFlag对象,在循环结束时kddFlag.flagValue是1.要解决这个问题,请将代码移到循环中。像这样:

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

答案 1 :(得分:2)

这是一个分配对象引用的问题,众所周知,甚至可以用其他语言进行。

我会给你一个更简单的例子:

假设你想要一个3x3矩阵,建模为数组,填充全部为零的行。

你可能想写作。

row = [0,0,0];
A = [];
for(j=0;j<3;++j) A[j] = row;

但是如果你改变A[0][0] = 10;

你看A[1][0],得到10,而不是0

这是因为只有一个rowA的所有元素都已分配给它。

要在Javascript中更正此模式,每次该对象都需要是一个新对象。这个 可以使用文字A[j]=[0,0,0]来完成,也可以A[j]=row.slice()创建一个浅层副本来解决一个级别或深层副本的问题。