In JavaScript primitive types are passed by value.
let counter = 1;
let factory = () => {
...
// The property `counter` in this object gets passed a value of the `counter` declared in the scope of `factory.js`.
// It does not get a reference.
return { counter, increment };
}
When you return the object from the factory
function, its property counter
is assigned a value from the counter
declared in the scope of factory.js
. This essentially means the counter
property on the object received a copy of the value – there is nothing linking the value of the counter
variable and the counter
property.
let counter = 1;
let factory = () => {
let increment = function () {
// The `++` operates on the `counter` variable declared in the scope of `factory.js`.
// There is no link between the value `counter` in the scope of `factory.js` and the `counter` as the property of the object returned.
// As a result when the `counter` variable is incremented, the `counter` property remains the same as the value initially passed to it.
counter++;
};
};
When you increment the counter
, you are incrementing the value of the variable declared in the scope of factory.js
. The variable's value is a Number
therefore being a primitive. Primitive values are passed by value so there is no link between the variable counter
and the property counter
.
Hopefully all that makes sense. If you want to do some more reading on this idea of passing by value (compared to passing by reference) you can see the following StackOverflow questions:
At this point in time you might be asking how can I fix this?
Instead of incrementing counter
you need to increment this.counter
. Like this:
let increment = () => {
this.counter++;
};
This works because the context of this
is the object being returned from the function factory
. The counter
property is on the variable you assigned the result of calling factory
.