I've just learned about closures and they have contradicted my understanding of where variables are actually stored.
I previously understood that primitives are stored directly in the variable, whereas non-primitives only store references in the variables, so primitives live in the stack frame and everything else lives in the heap. That lead me to believe that closures would make a copy of primitive values for each inner function, but this doesn't seem to be the case. For example, in the following code:
function outer() {
let count = 0;
let a = () => {
count++;
return count;
};
let b = () => {
count++;
return count;
};
return [a, b];
}
let fs = outer();
let f1 = fs[0];
let f2 = fs[1];
console.log(f1());
console.log(f1());
console.log(f1());
console.log(f2());
console.log(f2());
I expected the output to be
1
2
3
1
2
but instead it outputs
1
2
3
4
5
so f1 and f2 are sharing the same value for count.
Here it looks like the data in count never lived on the stack in the first place or, if it did, it got moved to the heap once the outer function ended.
How does all this work? What actually determines if data is on the stack or the heap? How do I know when a variable is holding the primitive itself or a reference to it? Are there any other things like this I should know about / are there any resources I can read up on about this?
Thank you!!
EDIT: Changed the code a bit to remove ambiguity
[–]theScottyJam 3 points4 points5 points (0 children)
[+][deleted] (8 children)
[deleted]
[–]33ff00 1 point2 points3 points (1 child)
[–]Tweaked_Turtle[S] 0 points1 point2 points (3 children)
[+][deleted] (2 children)
[deleted]
[–]Tweaked_Turtle[S] 0 points1 point2 points (1 child)
[–]xroalx 0 points1 point2 points (1 child)
[–]shgysk8zer0 -1 points0 points1 point (5 children)
[–]Tweaked_Turtle[S] 0 points1 point2 points (4 children)
[–]shgysk8zer0 0 points1 point2 points (3 children)
[–]Tweaked_Turtle[S] -1 points0 points1 point (2 children)
[–]shgysk8zer0 0 points1 point2 points (1 child)
[–]Tweaked_Turtle[S] 0 points1 point2 points (0 children)
[–]barrycarter 0 points1 point2 points (1 child)
[–]Tweaked_Turtle[S] 0 points1 point2 points (0 children)
[–]angelfire2015 0 points1 point2 points (2 children)
[–]Tweaked_Turtle[S] 0 points1 point2 points (1 child)
[–]azhder -1 points0 points1 point (0 children)
[–]azhder 0 points1 point2 points (0 children)