i am a bit obscure situation. mainly because i thought i already grasp closures. so basically what i want is to reset to default values a collection. so let say i have collectio
In javascript, composite data types are passed by reference, so, c.internalarray
and arr
both refer to the same value. Actually, you were on the right way, but you have to make a copy of the array before passing it to your immediately invoked function. For example :
c.on('reset', function (arr) {
return function () {
c.internalarray = arr;
}
}(c.internalarray.slice()));
That said, this technique will not create a deep copy, meaning that composite types contained in the array are still mutable from the outside of the immediately invoked function. In the code below, I've tried to simplify this situation in order to make things easier to understand, hopefully :
The variable a
refers to an array which contains two elements :
var a = [
1, // primitive value
{} // composite value
];
Let's make a shallow copy of a
and assign it to b
:
var b = a.slice();
// a -> [1, {}]
// b -> [1, {}]
// b === a -> false
Removing the first element from a
has no effect on b
:
a.shift();
// a -> [{}]
// b -> [1, {}]
But modifying the object contained in a
affects b
as well :
a[0].k = 'value';
// a -> [{ k: "value" }]
// b -> [1, { k: "value" }]
// a[0] === b[1] -> true
This has nothing to do with closures. Your issue can be seen simpler with this:
var internalarray = [{x},{y},{z}];
var arr = internalarray;
// "update" internalarray here
arr === internalarray // still true
internalarray = arr; // This statement has no effect
Just like in Java, every value in JavaScript is either a primitive or a reference (a pointer to an object). The value of arr
is a pointer to an object, the value of c
is a pointer to an object, the value of c.internalarray
is a pointer to an object, etc. Specifically in this case, c.internalarray
is a pointer to an array object. Assigning one pointer to another simply makes the second one point to the object pointed to by the first one. When you do arr = internalarray;
(or in your code, when you pass c.internalarray
in to a function as the parameter arr
), you have two pointers that point to the same object.
When you say "collection periodically get updated", you are never assigning (as in =
) to c.internalarray
itself. That's why arr === c.internalarray
remains true -- since you assigned one to the other initially, the only way they could be not equal is if you assigned to one of them later. Instead, I am guessing you are changing the elements of the array pointed by these two variables, using subscript operator like c.internalarray[foo] = bar;
or calling a method like c.internalarray.push(bar);
. Since you are changing the object pointed to, multiple pointers that point to it will be able to see the changes.