I’m learning javascript and I’m trying to figure out why my below function doesn’t work as expected. See the explanation in the 2 code examples:
// First time I call the shoplist function I pass [1] in the argument. Results are as I expect:
var shopitems = [];
function shoplist(ids) {
alert("ids passed to shoplist function: " + ids); // 1
alert("current ids in shopitems var: " + shopitems); // (empty)
shopitems.push(ids);
alert("ids in shopitems after pushing: " + shopitems); // 1
}
// Second time I call the shoplist functions I pass [1, 2] in the argument. Results are not what I would expect:
function shoplist(ids) {
alert("ids passed to shoplist function: " + ids); // 1, 2
alert("current ids in shopitems var: " + shopitems); // 1, 2 <--- Why is there 1, 2 and not only 1?
shopitems.push(ids);
alert("ids in shopitems after pushing: " + shopitems); // 1, 2, 1, 2
EDIT: Here is the full code (warning: probably very confusing): http://dpaste.org/wXMy5/
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 theshopitemsarray, when you modify the ids array before passing it to the second invocation ofshoplist(), you are also inadvertently modifyingshopitems[0]too. If each of your arguments toshoplist()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:
For more detailed explanation:
.push(ids)adds a whatever the contents ofidsas a new items onto the end of theshopitemsarray. 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:
In this code example, list will contain two elements and each will point to the same live version of
xwhich 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:
Or, make a copy of
x: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.