I have recently learnt there is a few ways to create a clousre ( not just returning a function from a function) but also referencing the function as a callback in an event listener. This creates a closure too which explains why you can call an innerFunction using an eventListener even after an IIFE has finsished executing and has not returned anything. I like to think the main power of a closure is that not only does it find a variable in an outer function to use in an inner function but it also updates its value so it can be stored e.g. you can push into an array and update it inside an outer function or update a score set as a primitive on an outer function.
However if you can create a closure via referencing a funciton via an event Listener then why can you not update a local variable everytime a funciton is called via an event listener, see below for what i am trying to get at.
function increaseScore(){
var score = 0;
score ;
console.log(score); // console.logs 1 everytime the event occurs despite the event listener creating a closure for this funciton
}
document.addEventListener("click", increaseScore);
function addScore(){
var score = 0;
return function (){ // this too is a closure created in a differnet way and increases everytime the event is called
score ;
console.log(score); // 1,2,3,4 etc everytime the event occurs
}
}
var keepScore = addScore();
document.addEventListener("click", keepScore);
Why is this the case ? They are both examples of closures, one via an event Listener, another via returning a function but only the function that returns a function gets updated from its original value of zero and is held in memory for everytime the function is called and the first funciton resets to zero everytime therfore only ever printing 1 to the console. I cand find an explanation anywhere?
CodePudding user response:
The first is not a closure, since var score
is declared within the function. Once you move that line outside of the function, it will work as expected (and the function will close over the global variable):
var score = 0;
function increaseScore(){
score ;
console.log(score);
}
document.addEventListener("click", increaseScore);
Better examples of how to create closures without return
ing them might be
var keepScore;
function addScore(){
var score = 0;
keepScore = function (){ // this too is a closure
score ;
console.log(score);
};
}
addScore();
document.addEventListener("click", keepScore);
function addScore(){
var score = 0;
function keepScore(){ // this too is a closure
score ;
console.log(score);
};
document.addEventListener("click", keepScore);
}
addScore();