开发者

JavaScript loop is changing the source array of data as well as the result - how come?

I am completely perplexed. I have an object containing a global "hashed" array of numbers (in objectA) that is referred in a loop that combines the numbers into a new series (in objectB).

var objectB = objectA[arrActive[0]]; 
for (i=1; i<arrActive.length; i++) {    
    var _this = arrActive[i];
    for (x=0; x<objectB.length; x++) {  
    objectB[x][1] += objectA[_this][x][1];  
    }
}

What's weird is that the values in objectA, the source array, are being incremented during the loop 开发者_如何学Python- but why? As far as I'm aware, I'm just reading from objectA to write to objectB!

This is frustrating because every time the function is called, the numbers are further inflated!

Working example on JSFiddle is here: http://jsfiddle.net/ZbWGH/ - have I completely misunderstood the += operator? I'm sure this is a simple issue to understand.

Thanks in advance for any help!


You're putting reference to the instance objectA['ONE'] in variable called objectB - any change in that variable will indeed change the actual value.

Instead you might be interested in getting clone or "clean copy" of the array into objectB and this way it won't change the original array.

Simple function that will do this is:

function CopyArray(arr) {
    var clone = [];
    for (var i = 0; i < arr.length; i++) {
        var subArray = [];
        for (var j = 0; j < arr[i].length; j++)
            subArray.push(arr[i][j]);
        clone.push(subArray);
    }
    return clone;
}

And to use it:

var objectB = CopyArray(objectA[arrActive[0]]); 

Updated jsFiddle: http://jsfiddle.net/yahavbr/ZbWGH/1/


Further more A += B is like A = A + B, so you modify objectA.


Do you know C? References/pointers in C are a good way to understand komplex variables in Javascript. "Komplex" meaning everything that is not Number, String, Boolean - everything else is "Object". Variables for the komplex types (Objects) are indeed like pointers. If you know the concepts of "call by reference" and "call by value", in Javascript it's neither, sort of: If you give objects to functions the "pointer" itself is call by value, but the value is a reference to the object (really to the area on the heap where the object is stored, even though JS programmers don't handle heap like in C/C++ it still is where stuff is stored). Example:

function fn (a) {
  //changing the argument itself does NOT change the original object
  a = null;
  //but changing its properties does:
  a.foo = 42;
}

var o = { foo:1, bar:2 };

fn(o);

So now it should become clear why you have to clone an object if you want real "call by value". This implementation was chosen for JS because otherwise every single time a function is called with a non-primitive type the heap would have to be copied over, and 99% of the time that just is not necessary. The "true" spirit of functional programming would of course be pure call by value, here we see practical life (performance and memory usage) considerations intruding upon theory :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜