So far this is my thought process:
In JS primitives are pass by value, and objects are pass by reference.
let var1 = 10 // var1 is assigned a reference to the primitive 10
let var2 = var1 // var1 is evaluated to the primitive 10, var2 is assigned a reference to the primitive 10
// var1 and var2 are independent. This is pass by value
const obj1 = {} // obj1 is given a reference to the object created in memory by the object literal
const obj2 = obj1 // obj2 is given a reference to the exact same object obj1 is pointing to
// obj1 and ob2 are pointing to the same object, they are not independent variables. This is pass by reference
What I am confused about is closures. In closures, it seems that everything is passed by reference. Even variables that are referencing primitives.
function func() {
let a = 0;
return [
function () {
a++;
return a;
},
function () {
a++;
return a;
},
];
}
const [a, b] = func();
console.log(a(), b()); //will result in logging 1, 2
In this example the func defines a local variable a to 0, then includes it in the closure of 2 anonymous functions that are being returned. Then by mutating a from either function, its clear that they are referencing the same spot in memory.
Previously I had thought both functions just created an unaccessable object to store its closure in and copied over the variables. If this was the case then the variables would be copied by value, and each anonymous function would have a variable named a in their closure that referenced the primitive 0. Then you could safely mutate a in each function.
But now it's clear that instead, the functions have a reference to the actual variable a that was defined when func was executed.
Is my understanding of how closures work correct? And is there any other way to reference a variable itself, instead of the primitive that it points to?