1

I am working on a project in which I have a problem of one array variable suddenly containing the same as another one. With the help of the lazy man's alert prompts, I have narrowed the problem down to this piece of code, where everything suddenly goes wrong:

// The array "data" is the result of a JSON request - this works fine..
// "data" is a two-dimensional array.
allShowsVars = data.slice();
allShowsVars.sort(function(a, b) {
    var aL = a[1].toLowerCase(), bL = b[1].toLowerCase();
    if(aL < bL) return -1;
    else if(aL > bL) return 1;
    else return 0;
});
// At this moment, the allShowsVars variable holds the right contents from the data array..
showsVars = allShowsVars.slice(); // Here, we make a copy of allShowsVars..
for(var iS = 0, sPos; typeof showsVars[iS] != 'undefined'; iS++) {
    sPos = showsVars[iS][1].indexOf(" - Season ");
    if(sPos != -1) {
        showsVars[iS][1] = showsVars[iS][1].slice(0,sPos);
        if(iS > 0) {
            if(showsVars[(iS-1)][1] == showsVars[iS][1]) showsVars.splice(iS,1);
            iS--;
        }
    }
}
// I changed showsVars in the above for loop, cutting out " - Season ......" in a lot of entries.

Now, allShowsVars also has the new, changed contents from showsVars. Why??? The variables are not linked together! I am thinking I missed something obvious somewhere. I just need someone clever enough to see it :)

AstroCB
  • 12,337
  • 20
  • 57
  • 73
markj
  • 137
  • 10
  • 1
    `slice()` copies the array, but not the values therein. `showsVars[x]` and `allShowsVars[x]` still point to the same object. – georg Sep 25 '14 at 08:09
  • Thank you very much. I missed that little detail. – markj Sep 25 '14 at 08:56

2 Answers2

4

This is from the documentation of Array.prototype.slice() from MDN.

For object references (and not the actual object), slice copies object references into the new array. Both the original and new array refer to the same object. If a referenced object changes, the changes are visible to both the new and original arrays.

This is what happening in your case.

You can use this hack to deep copy an array:

var deepCopy = JSON.parse(JSON.stringify(sourceArray));

See here and here for deep copying of JavaScript arrays/objects.

sampathsris
  • 21,564
  • 12
  • 71
  • 98
  • Accepted as it is the most comprehensive answer with solutions. Thank you very much. – markj Sep 25 '14 at 09:01
  • 1
    Just found this one, which really gives some good insight as well as speed comparisons: http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object – markj Sep 25 '14 at 09:31
2

slice() only performs a shallow copy. Primitive values are copied directly, but nested objects are internally treated as references so both arrays end up pointing to the same objects.

Alnitak
  • 334,560
  • 70
  • 407
  • 495