Hola, si llegaste aqui es porque en la clase ¿Qué es closure? te quedaron muchas dudas sobre lo que pasa por debajo.
Espero que este aporte ayude a entender lo que pasa , vamos a ver que es lo que pasa con el ejercicio moneyBox()
gráficamente con ayuda de JavaScript Visualizarer.
JavaScript Visualizer
Javascript Visualizer es una herramienta de visualización de contexto de ejecución, hoisting, closures y scopes en JavaScript.
<h3>Instrucciones</h3>El vizualizador aún esta en fase Beta, lo que significa que por ahora solo soporta ES5, asi que tendermos que hacer ciertos cambios es el código de la clase.
const moneyBox = () => {
let saveCoins = 0
const countCoins = (coins) => {
saveCoins += coins
console.log(`MoneyBox: $${saveCoins}`)
}
return countCoins
}
let myMoneyBox = moneyBox()
myMoneyBox(4) // 4
myMoneyBox(6) // 10
myMoneyBox(10) // 20
Con estos cambios el visualizador ejecutara nuestro código sin problemas.
var moneyBox = function() {
var saveCoins = 0;
var countCoins = function(coins) {
saveCoins += coins;
console.log(saveCoins);
};
return countCoins;
};
var myMoneyBox = moneyBox();
myMoneyBox(4); //4
myMoneyBox(6); //10
myMoneyBox(10); //20
<h1>Ejecución</h1>
En la primera ejecución y en cada llamada a una nueva función se crea un contexto de ejecución la cual tiene dos fases:
- Creación -> En el contexto objeto global se crean el el objeto global, el objeto this y los espacios me memoria para las funciones y variables con un valor por defecto de
undefined
. - Ejecución -> Se ejecuta linea por linea definiendo los valores reales de tus variables y funciones.


Como se puede obserbar el valor de moneyBox
paso de undefined
a fn()
ya que su contenido es una función.
El siguiente línea tiene algo más de complejidad.
var myMoneyBox = moneyBox();
//moneyBox() se ejecuta
//y lo que retorna se guarda en myMoneyBox
Cuando llegamos a esta línea debemos ejecutar primero moneyBox()
el cual ya tiene definido una función fn()
que apunta a la línea 1.
Cada vez que se invoca una función se crea un nuevo contexto de ejecución, tambien crea un objeto
this
pero a diferencia del contexto global, crea un objeto llamadoarguments
.

-
Tambien tiene las dos fases de creación y ejecución
-
El objeto
arguments
simplemente recibe los argumentos pasados cuando invocamos la funcion, es este caso queda vacío. -
Las variables
saveCoins
ycountCoins
se declaran con el valor por defecto deundefined
.
Este es el bloque de código que se ejecutará.
var moneyBox = function() {
var saveCoins = 0;
var countCoins = function(coins) {
saveCoins += coins;
console.log(saveCoins);
};
return countCoins;
};

-
Las variable
saveCoins
obtiene su valor0
ycountCoins
hará referencia a una funciónfn()
. -
La función retornara
countCoins: fn()
.

-
Cuando
moneyBox()
termine de ejecutarse, JavaScript Visualizer creara unclosure scope
. -
Dentro de
Closure Scope
existe el mismo entorno de ejecución que enmoneyBox
es este caso => anonymous Execution Context.
Esto pasa debido a que tenemos una función anidada dentro de otra.

myMoneyBox
que esta en el contexto global recibe una funciónfn()
que hace referencia alClosure Scope
.
Dado que myMoneyBox
ahora es una función hace refencia a función que se almacena en countCoins
que recibe un parametro coins
var moneyBox = function() {
var saveCoins = 0;
//==============================
var countCoins = function(coins) {
saveCoins += coins;
console.log(saveCoins);
};
//==============================
return countCoins;
};
<h4>Últimas lineas de código</h4>
myMoneyBox(4); //4
myMoneyBox(6); //10
myMoneyBox(10); //20
Esto es lo que sucede cuando ejecutamos myMoneyBox(4)
.

- Un nuevo contexto de ejecución se crea dentro de
Closure scope
en la fase de creación. arguments
recibe un parámetro que esta vez es4
.- Dado el el nombre del parametro es
coins
esta se define como variable local dentro de esta función.

- Durante la fase de efecución la línea
saveCoins += coins
suma0 + 4
y lo almacena ensaveCoins
del closure scope. - Luego muestra en consola el número
4
que al no existir en la anonymous Execution Context la busca en el scope padre más cercano que es Closure Scope
El Closure Scope queda así con el valor de saveCoins
modificado

Notaran que con cada llamada a la función guardara el dato es su contexto de ejecución.
Cuando ejecutamos myMoneyBox(6)
primero en fase de creación y luego en ejecución.
Creación
Ejecucuión
Cuando ejecutamos myMoneyBox(10)
primero en fase de creación y luego en ejecución.
Creación
Ejecucuión
Conclusión
Si algunas cosas no te quedaron claras les recomiento el siguiente artículo.
Tambien pudes probar el código tu mismo en el siguiente enlace.
Curso de Closures y Scope en JavaScript 2020