I feel as though my knowledge with closures is almost there, but I'm struggling to grasp exactly why this first code snippet logs 0 (is a stale closure) however, the second code snippet works and logs the updated value ..
Is this some kind of reference issue?
In the first example, are we not tracking the reference of count and only assigning its initial value to message?
By moving the message variable inside of the log function are we somehow telling JS to track the reference of the count value?
function createIncrement() {
let count = 0;
function increment() {
count ;
}
let message = count;
function log() {
console.log(message);
}
return [increment, log];
}
const [increment, log] = createIncrement();
increment();
log();
// this will log 0
function createIncrement() {
let count = 0;
function increment() {
count ;
}
function log() {
let message = count;
console.log(message);
}
return [increment, log];
}
const [increment, log] = createIncrement();
increment();
log();
// this will log 1
CodePudding user response:
In the first example, are we not tracking the reference of count and only assigning its initial value to message?
By moving the message variable inside of the log function are we somehow telling JS to track the reference of the count value?
This is the thing you're struggling with. Let's try to decompose what happens there.
At its core, it's just about this:
let count = 0;
let message = count;
console.log(message);
count ; // it's exactly the same as count = count 1;
console.log(message); // still prints 0
This has nothing to do with closures, and everything to do about numbers being immutable values. When we increment count
we are assigning to the variable a new instance of a number with the value 1.
message
is still pointing to the old instance (value, in this case it's the same), so the log is going to print the same old value.
If I understand your misunderstanding correctly (!) you're picturing that count
is a container in which you can insert a numeric value, which is slightly wrong.
It is a pointer to a numeric and immutable value, that sits in memory somewhere. When you do message = count
you ensure message and count are pointing to the same memory address, that contains a 0
.
When you write count
, you are allocating a new number in memory, somewhere, for the number 1, and count
now points to the new object. message
is unaffected by this operation. This is the crucial bit that I think is not crystal clear.
In your second example, message
is reassigned every time you log, so it will always hold a reference to the correct value.