Recientemente aprendí que hay algunas formas de crear un cierre (no solo devolver una función desde una función), sino también hacer referencia a la función como una devolución de llamada en un detector de eventos. Esto también crea un cierre que explica por qué puede llamar a una función interna usando un eventListener incluso después de que un IIFE haya terminado de ejecutarse y no haya devuelto nada.
Me gusta pensar que el poder principal de un cierre es que no solo encuentra una variable en una función externa para usarla en una función interna, sino que también actualiza su valor para que pueda almacenarse. Por ejemplo, puede ingresar a una matriz y actualizarla dentro de una función externa o actualizar un conjunto de puntajes como una primitiva en una función externa.
Sin embargo, si puede crear un cierre haciendo referencia a una función a través de un detector de eventos, entonces ¿por qué no puede actualizar una variable local cada vez que se llama a una función a través de un detector de eventos? Vea a continuación a lo que estoy tratando de llegar.
function increaseScore(){ var score = 0; score ++; console.log(score); // console.logs one 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 different way // and increases every time the event is called score ++; console.log(score); // 1, 2, 3, 4, etc. every time the event occurs } } var keepScore = addScore(); document.addEventListener("click", keepScore);¿Por qué es este el caso? Ambos son ejemplos de cierres, uno a través de un Event Listener, otro a través de la devolución de una función, pero solo la función que devuelve una función se actualiza desde su valor original de cero y se mantiene en la memoria cada vez que se llama a la función y la primera la función se restablece a cero cada vez y, por lo tanto, solo imprime 1 en la consola. No encuentro explicación por ningún lado.
El primero no es un cierre, ya que var score se declara dentro de la función. Una vez que mueva esa línea fuera de la función, funcionará como se esperaba (y la función se cerrará sobre la variable global):
var score = 0; function increaseScore(){ score ++; console.log(score); } document.addEventListener("click", increaseScore); Mejores ejemplos de cómo crear cierres sin return podrían ser
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();