Your problem will occur if you are modifying the SAME ids array before calling the second invocation of shoplist()
. Because javascript passes arrays by reference and only a reference goes into the shopitems
array, when you modify the ids array before passing it to the second invocation of shoplist()
, you are also inadvertently modifying shopitems[0]
too. If each of your arguments to shoplist()
the first and second time you call it are completely separate arrays, you will not have this problem, but if the second invocation is just being passed a modification of the first array, you will have this problem.
The quick illustration is this:
// this will not have the problem because each call to shoplist
// is passing a completely separate array
var list = [1];
shoplist(list);
list = [1,2]; // create new array
shoplist(list); // shoplist is [[1], [1,2]]
// this will have the problem because they are the same array
var list = [1];
shoplist(list);
list.push(2); // modify first array
shoplist(list); // shoplist is [[1,2], [1,2]] and both array elements are actually the same array
For more detailed explanation: .push(ids)
adds a whatever the contents of ids
as a new items onto the end of the shopitems
array. So, each time you call shoplist, you get a new item on the end of shopitems. But, since the item you are adding is an array, it adds a reference to that array, not a copy of that array. If you subsequently change that array, the shopitems array entry will point to the changed version of the array.
You can see that in this code:
var x = [];
var list = [];
x.push(1); // contains contains [1]
list.push(x); // list is [[1]]
x.push(2); // x is [1,2]
list.push(x); // list is [[1,2], [1,2]] (contains two references to x)
In this code example, list will contain two elements and each will point to the same live version of x
which contains [1,2]
.
This is because by default, javascript passes references for things like arrays and objects. When you push an array element into your container array, it is not putting a static copy of that variable into the array. It's putting a pointer to the original variable. If you then change the original variable, that change is reflected in the array too.
To separate the second entry from the first, you either need to consciously make a copy of the first array and push that copy into the container array or you need to create a new array from scratch and push it into the container array.
For example, here are a couple ways to create two independent elements in the container array:
var x = [];
var list = [];
x.push(1); // contains contains [1]
list.push(x); // list is [[1]]
x = []; // set x to a new array (the old version of x is still in list)
x.push(1); // x is [1]
x.push(2); // x is [1,2]
list.push(x); // list is [[1], [1,2]] (contains two separate items)
Or, make a copy of x
:
var x = [];
var list = [];
x.push(1); // contains contains [1]
list.push(x); // list is [[1]]
x = x.slice(0); // make a copy of x, the old version of x is still in list
x.push(1); // x is [1]
x.push(2); // x is [1,2]
list.push(x); // list is [[1], [1,2]] (contains two separate items)
The important thing to remember here is that in javascript, object assignment or array assignment does not make a copy. It just assigns a pointer to the original data structure. If you change the original data structure, that will be reflected in any assignments you've made.
If you a copy, you have to either explicitly make a new array or explicitly make a copy.