<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pedro Midueño</title>
    <description>The latest articles on DEV Community by Pedro Midueño (@pedro_midueno).</description>
    <link>https://dev.to/pedro_midueno</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4029013%2Fc2b3b12a-20dc-4937-bf87-f11b0fc6f013.jpg</url>
      <title>DEV Community: Pedro Midueño</title>
      <link>https://dev.to/pedro_midueno</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pedro_midueno"/>
    <language>en</language>
    <item>
      <title>Closures a fondo en JavaScript</title>
      <dc:creator>Pedro Midueño</dc:creator>
      <pubDate>Mon, 21 Sep 2026 18:11:07 +0000</pubDate>
      <link>https://dev.to/pedro_midueno/closures-a-fondo-en-javascript-4hfh</link>
      <guid>https://dev.to/pedro_midueno/closures-a-fondo-en-javascript-4hfh</guid>
      <description>&lt;p&gt;Cuando comencé a aprender sobre las closures, escuché y leí muchas veces explicaciones como esta: &lt;em&gt;"Una closure es una función que retorna otra función, y la función que se retorna usa variables que se definieron en el cuerpo de la función padre"&lt;/em&gt;, o varias explicaciones que prácticamente se referían a algo similar a esta definición, y aunque en el escenario que se expone en esta definición se forma una closure, la definición como tal no es 100% correcta y hay muchas otras cosas que podemos aprender para profundizar en el uso y comportamiento de las closures.&lt;/p&gt;

&lt;p&gt;En este artículo exploramos a fondo qué son las closures, así como otros conceptos del lenguaje JavaScript, como el entorno léxico, que nos ayudarán a comprender el funcionamiento interno de las mismas. Aprenderemos cómo es que estos conceptos se relacionan directamente con los alcances de bloque(scopes) introducidos en la especificación ECMAScript 6, así como la relación que tienen con las closures, y cómo el entender estos mecanismos nos ayudarán a comprender cómo es que al usar closures se pueden mantener "vivas" variables, constantes, parámetros y demás dentro de su alcance, incluso cuando la función donde fueron creadas hayan terminado su ejecución. Si te interesa conocer todo esto te invito a leer hasta al final porque hay mucha información interesante y seguro que algo nuevo aprendes hoy.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué son las closures?
&lt;/h2&gt;

&lt;p&gt;Un closure es la combinación de una función agrupada dentro de otra con referencias a su estado adyacente. Veamos el siguiente ejemplo para entenderlo un poco mejor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pemid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// hijo es la función interna que forma el closure&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Podemos acceder a la variable nombre&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;hijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Se muestra en la consola 'pemid'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo podemos ver que en la función &lt;code&gt;hijo&lt;/code&gt; se lee la variable declarada en la función &lt;code&gt;padre&lt;/code&gt;, prácticamente, en este ejemplo la closure se crea entre al función &lt;code&gt;hijo&lt;/code&gt; y la variable declarada en la función &lt;code&gt;padre&lt;/code&gt;. Si has programado con JavaScript o TypeScript durante un tiempo te habrás percatado de que realmente esto se relaciona directamente con otro concepto que también es muy importante desde inicio que es el &lt;strong&gt;&lt;em&gt;scope&lt;/em&gt;&lt;/strong&gt; o alcance, y esto mismo se relaciona con los conceptos de &lt;strong&gt;&lt;em&gt;Ámbito Léxico&lt;/em&gt;&lt;/strong&gt; y &lt;strong&gt;&lt;em&gt;Entorno Léxico&lt;/em&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Alcance con &lt;code&gt;let&lt;/code&gt; y &lt;code&gt;const&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Antes de conocer lo que son el Ámbito Léxico y el Entorno Léxico, conozcamos el contexto en que estos conceptos fueron concebidos en JavaScript. En JavaScript tradicional, antes de la llegada de la especificación ECMAScript 6(ES6), las variables eran declaradas con la palabra reservada &lt;code&gt;var&lt;/code&gt;, con estas variables, JavaScript hacia un proceso de &lt;strong&gt;&lt;em&gt;hoisting&lt;/em&gt;&lt;/strong&gt;, el cual &lt;em&gt;"elevaba"&lt;/em&gt; la declaración de las variables al inicio de la ejecución del archivo o módulo, lo cual hacía que pudieras usarlas incluso antes de su declaración o inicialización explícita, tal y como se muestra en el siguiente ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="c1"&gt;// declarada, inicializada con undefined&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="c1"&gt;// la variable "y" se puede usar antes de su declaración debido al proceso de hoisting &lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="c1"&gt;// Declarada, "hoisteada" e inicializada en undefined&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto como te puedes imaginar, podía causar bugs muy complicados de encontrar. Con la llegada de ES6, JavaScript introdujo nuevas formas de declarar variables y constantes, esto como sabemos es con las palabras reservadas &lt;code&gt;let&lt;/code&gt; y &lt;code&gt;const&lt;/code&gt;, con esto llegaron nuevos conceptos, entre los cuales están las &lt;strong&gt;&lt;em&gt;Temporal Dead Zones(TDZ)&lt;/em&gt;&lt;/strong&gt; o zonas muertas temporales, y los &lt;strong&gt;&lt;em&gt;scopes&lt;/em&gt;&lt;/strong&gt; o alcances de bloque.&lt;/p&gt;

&lt;p&gt;La TDZ es la zona entre el inicio del bloque y la declaración de una variable, la cual prácticamente solo la vemos cuando declaramos una variable con &lt;code&gt;let&lt;/code&gt;, ya que al momento de declarar una constante con &lt;code&gt;const&lt;/code&gt; debemos obligatoriamente inicializarlas con un valor. Gracias a esto, si intentamos hacer algo parecido a nuestro ejemplo anterior, pero ahora declarando la variable con &lt;code&gt;let&lt;/code&gt; en lugar de &lt;code&gt;var&lt;/code&gt;, tendremos el siguiente error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ReferenceError: Cannot access 'x' before initialization&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gracias a la TDZ, ahora si intentamos usar una variable antes de su declaración tendremos este error de &lt;strong&gt;&lt;em&gt;&lt;code&gt;Reference Error: cannot access 'x' before initialization&lt;/code&gt;&lt;/em&gt;&lt;/strong&gt;. Es importante que sepamos que la TDZ solo es un mecanismo que hace que no se pueda acceder a una variable antes de su declaración, mas no de su inicialización, puesto que como ocurre con las variables declaradas con &lt;code&gt;var&lt;/code&gt;, si podemos acceder a ellas incluso antes de su inicialización ya que también JavaScript las inicializa en &lt;code&gt;undefined&lt;/code&gt; como se muestra a continuación:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otro concepto importante que llegó junto con ES6 es el &lt;strong&gt;&lt;em&gt;scope&lt;/em&gt;&lt;/strong&gt; o alcance por bloque. Como vimos en nuestro ejemplo usando &lt;code&gt;var&lt;/code&gt;, la variable &lt;code&gt;y&lt;/code&gt;, declarada dentro de un bloque, podía ser accedida desde fuera de las llaves --las llaves delimitan el bloque(este comportamiento sigue existiendo en JavaScript moderno, por eso ya no se recomienda declarar variables con &lt;code&gt;var&lt;/code&gt;). El alcance por bloque se refiere a que las variables o constantes declaradas con &lt;code&gt;let&lt;/code&gt; o &lt;code&gt;const&lt;/code&gt;, solo pueden ser leídas en el mismo bloque o en bloques adyacentes &lt;em&gt;"hijos"&lt;/em&gt;, pero las variables declaradas en bloques &lt;em&gt;"hijos"&lt;/em&gt; no pueden ser leídas o accedidas desde bloques &lt;em&gt;"padres"&lt;/em&gt; o superiores, veamos el siguiente ejemplo para entenderlo mejor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;var1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;var2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;var1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'outer'&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;var2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'inner'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;var1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'outer'&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;var2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// ReferenceError: var2 is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este último ejemplo, la variable &lt;code&gt;var1&lt;/code&gt; puede ser accedida desde el bloque del &lt;code&gt;if&lt;/code&gt; puesto que es una variable que se declaró en un bloque &lt;em&gt;"padre"&lt;/em&gt;(también se puede decir que se declaró en el ámbito externo), sin embargo como vemos al final, cuando intentamos acceder a &lt;code&gt;var2&lt;/code&gt;, que está declarada dentro del bloque &lt;em&gt;"hijo"&lt;/em&gt;(dentro de las llaves del &lt;code&gt;if&lt;/code&gt;), JavaScript nos arroja un &lt;em&gt;ReferenceError&lt;/em&gt;, pues como mencionamos antes, los bloques &lt;em&gt;"padre"&lt;/em&gt; no pueden acceder a las variables declaradas en los bloques (o ámbitos) &lt;em&gt;"hijo"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Con esto, ahora los bloques en JavaScript crean ámbitos o &lt;em&gt;scopes&lt;/em&gt;, como lo vimos en este último ejemplo, el alcance de la variable &lt;code&gt;var2&lt;/code&gt;, sólo es dentro del bloque entre las llaves de la sentencia &lt;code&gt;if&lt;/code&gt;, por este comportamiento llegaron otros conceptos nuevos que debemos conocer para comprender a fondo las closures, los cuales son el &lt;strong&gt;&lt;em&gt;Ámbito/Alcance Léxico&lt;/em&gt;&lt;/strong&gt;(o &lt;em&gt;lexical scope&lt;/em&gt;) y el &lt;strong&gt;&lt;em&gt;Entorno Léxico&lt;/em&gt;&lt;/strong&gt;(o &lt;em&gt;lexical environment&lt;/em&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Ámbito Léxico y Entorno Léxico
&lt;/h3&gt;

&lt;p&gt;Con la llegada de &lt;code&gt;let&lt;/code&gt; y &lt;code&gt;const&lt;/code&gt; en ES6, como mencionamos, los bloques crean &lt;em&gt;scopes&lt;/em&gt;, con esto, podemos definir el &lt;strong&gt;&lt;em&gt;Ámbito Léxico&lt;/em&gt;&lt;/strong&gt; como un concepto o regla del lenguaje JavaScript que determina la visibilidad y accesibilidad de las variables según donde se escribieron &lt;em&gt;"físicamente"&lt;/em&gt; en el código; por otro lado, el &lt;strong&gt;&lt;em&gt;Entorno Léxico&lt;/em&gt;&lt;/strong&gt; es la implementación física que usa el motor de JavaScript para almacenar esas variables y mantener la referencia al ámbito padre.&lt;/p&gt;

&lt;p&gt;En otras palabras, el &lt;strong&gt;&lt;em&gt;Ámbito Léxico&lt;/em&gt;&lt;/strong&gt; son las reglas del estándar ECMAScript que determinan cuál es el alcance o &lt;em&gt;scope&lt;/em&gt; de las variables, mientras que el &lt;strong&gt;&lt;em&gt;Entorno Léxico&lt;/em&gt;&lt;/strong&gt; es el lugar físico en memoria donde se almacena la estructura de datos de las variables de una función, el &lt;strong&gt;&lt;em&gt;Entorno Léxico&lt;/em&gt;&lt;/strong&gt; se compone de dos elementos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El &lt;strong&gt;&lt;em&gt;Registro de Entorno&lt;/em&gt;&lt;/strong&gt;(o &lt;em&gt;Environment Record&lt;/em&gt;): Es donde se almacenan las variables, constantes, funciones y parámetros   locales o declarados directamente dentro del scope de la función&lt;/li&gt;
&lt;li&gt;Una referencia externa: La referencia o enlace al &lt;em&gt;entorno léxico&lt;/em&gt; adyacente superior (&lt;em&gt;Outer Lexical Environment&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Prácticamente es el &lt;em&gt;entorno léxico&lt;/em&gt; lo que permite que las closures puedan crearse y lo que explica cómo funciona a más bajo nivel el alcance de las variables y constantes.&lt;/p&gt;

&lt;p&gt;Un dato interesante y curioso es que algunas fuentes en internet mencionan que el entorno léxico de una función es almacenado en una&lt;br&gt;
variable oculta llamada &lt;code&gt;[[Environment]]&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Funciones que retornan funciones
&lt;/h2&gt;

&lt;p&gt;Veamos de nuevo nuestro primer ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pemid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// hijo es la función interna que forma el closure&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Podemos acceder a la variable nombre&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;hijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Se muestra en la consola 'pemid'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, la variable &lt;code&gt;nombre&lt;/code&gt; solo es usada dentro de la función &lt;code&gt;hijo&lt;/code&gt; y solo se imprime en consola, una vez la función &lt;code&gt;padre&lt;/code&gt; termina de ejecutarse, la variable &lt;code&gt;nombre&lt;/code&gt; es marcada como lista para limpieza por el recolector de basura(&lt;em&gt;garbage collector&lt;/em&gt;) y la liberación de su espacio en memoria, lo que hace que una vez terminada de ejecutarse ya no se pueda volver a acceder a la variable &lt;code&gt;nombre&lt;/code&gt; de ninguna manera.&lt;/p&gt;

&lt;p&gt;Ahora bien, llegamos a la parte que se suele enseñar comúnmente cuando se explican las closures en JavaScript, las funciones que retornan funciones que tienen una referencia a una variable o constante declarada en la función padre, veamos este ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pemid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hijo&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;funcionHijo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// guardamos la referencia a la función hijo&lt;/span&gt;
&lt;span class="nf"&gt;funcionHijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'pemid'&lt;/span&gt;
&lt;span class="nf"&gt;funcionHijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'pemid'&lt;/span&gt;
&lt;span class="nf"&gt;funcionHijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'pemid'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos acceder a la variable &lt;code&gt;nombre&lt;/code&gt; incluso cuando la función donde fue declarada ya terminó su ejecución!!! 🤯&lt;/p&gt;

&lt;p&gt;Puede que esto te sorprenda, o puede que no porque es algo que ya has visto muchas veces y sabes que es el comportamiento que tienen las closures, pero, ¿sabes realmente por qué podemos seguir accediendo a la variable &lt;code&gt;nombre&lt;/code&gt; incluso después de que termina de ejecutarse la función &lt;code&gt;padre&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Ahora que hemos aprendido lo que es el &lt;em&gt;entorno léxico&lt;/em&gt;, no es tan complicado entender esto, prácticamente podemos resumir lo que está pasando con lo siguiente:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Se declara la función &lt;code&gt;padre&lt;/code&gt;, la cual en su cuerpo declara la variable &lt;code&gt;nombre&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dentro de la función &lt;code&gt;padre&lt;/code&gt; también se declara la función &lt;code&gt;hijo&lt;/code&gt;, como vimos antes, en la función &lt;code&gt;hijo&lt;/code&gt; se crea un    &lt;em&gt;entorno léxico&lt;/em&gt;, en el cual hay una referencia hacia el &lt;em&gt;entorno léxico&lt;/em&gt; superior(el de la función &lt;code&gt;padre&lt;/code&gt;) y dentro de este    último está la variable &lt;code&gt;nombre&lt;/code&gt; que está siendo usada dentro de la función &lt;code&gt;hijo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;La función &lt;code&gt;hijo&lt;/code&gt; es retornada por la función &lt;code&gt;padre&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Se declara la constante &lt;code&gt;funcionHijo&lt;/code&gt;(&lt;code&gt;const funcionHijo = padre()&lt;/code&gt;), ahora en esta constante se guarda lo que retorna la función &lt;code&gt;padre&lt;/code&gt;, que es la referencia a la función &lt;code&gt;hijo&lt;/code&gt; que fue declarada dentro de la función &lt;code&gt;padre&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Se termina de ejecutar la función &lt;code&gt;padre&lt;/code&gt;, JavaScript intente hacer la limpieza o recolección de las variables declaradas en la    función &lt;code&gt;padre&lt;/code&gt; porque ya terminó su ejecución, sin embargo, al ver la variable &lt;code&gt;nombre&lt;/code&gt; se da cuenta que esta sigue siendo    referenciada dentro del &lt;em&gt;entorno léxico&lt;/em&gt; de la función &lt;code&gt;hijo&lt;/code&gt;, la cual sigue teniendo una referencia &lt;em&gt;"viva"&lt;/em&gt;, la constante    &lt;code&gt;funcionHijo&lt;/code&gt;, por lo que al no poderla destruir, la pasa a la memoria heap, donde vivirá hasta que ya no sea utilizada ni    referenciada en ningún lugar.&lt;/li&gt;
&lt;li&gt;Gracias a que esta referencia ahora se queda &lt;em&gt;"viva"&lt;/em&gt;, al ejecutar &lt;code&gt;funcionHijo()&lt;/code&gt; más adelante, podemos seguir viendo en la    consola &lt;code&gt;'pemid'&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Con esto ahora ya conoces más a fondo cómo es que funcionan las closures, ahora bien, solo para complementar esto, podríamos hacer una limpieza manual de la referencia a la variable &lt;code&gt;nombre&lt;/code&gt; de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pemid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;hijo&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// reemplazamos const por let para poder cambiar su valor más adelante&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;funcionHijo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;funcionHijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'pemid'&lt;/span&gt;
&lt;span class="nf"&gt;funcionHijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'pemid'&lt;/span&gt;
&lt;span class="nf"&gt;funcionHijo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'pemid'&lt;/span&gt;

&lt;span class="c1"&gt;// Al cambiar ahora el valor guardado en la variable funcionHijo por undefined&lt;/span&gt;
&lt;span class="c1"&gt;// se pierde la referencia de la función hijo y su entorno léxico, por lo que&lt;/span&gt;
&lt;span class="c1"&gt;// ahora la variable nombre no se usa en ningún lugar por lo que puede ser&lt;/span&gt;
&lt;span class="c1"&gt;// destruida por el garbage collector&lt;/span&gt;
&lt;span class="nx"&gt;funcionHijo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usando Closures
&lt;/h2&gt;

&lt;p&gt;Hagamos algunos ejemplos de uso de closures para entender mejor algunas formas de usar closures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creando fábricas de funciones
&lt;/h3&gt;

&lt;p&gt;Veamos esta función:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;crearTablaDeMultiplicar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;factor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;multiplier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;multiplier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La función &lt;code&gt;crearTablaDeMultiplicar&lt;/code&gt; recibe el parámetro &lt;code&gt;factor&lt;/code&gt;, el cual se usa en la función anónima que retorno, esta función que retorna también recibe un parámetro &lt;code&gt;multiplier&lt;/code&gt;, como podemos ver en el código, se imprimirá en consola el producto resultante entre &lt;code&gt;factor&lt;/code&gt; y &lt;code&gt;multiplier&lt;/code&gt;, lo cual podemos usar de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Tabla del 5&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_5x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crearTablaDeMultiplicar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 15&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 20&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 25&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 30&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 35&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 40&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 45&lt;/span&gt;
&lt;span class="nf"&gt;_5x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 50&lt;/span&gt;

&lt;span class="c1"&gt;// Tabla del 7&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;_7x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crearTablaDeMultiplicar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 7&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 14&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 21&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 28&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 35&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 42&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 49&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 56&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 63&lt;/span&gt;
&lt;span class="nf"&gt;_7x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 70&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, la función &lt;code&gt;crearTablaDeMultiplicar&lt;/code&gt; es una  fábrica de funciones, ya que su ejecución crea nuevas funciones con algunas &lt;em&gt;"configuraciones predeterminadas"&lt;/em&gt; que serán compartidas las veces que se ejecute la función, en este caso, la &lt;em&gt;"configuración predeterminada"&lt;/em&gt; es lo que se envía como argumento al parámetro &lt;code&gt;factor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como podemos ver, los &lt;em&gt;entornos léxicos&lt;/em&gt; no se mezclan, si no que se crea uno cada vez que se guarda una nueva referencia de la función interna que forma el closure, y de esta forma manteniendo su independencia. De esta manera en la declaración &lt;code&gt;const _5x = crearTablaDeMultiplicar(5)&lt;/code&gt;, en &lt;em&gt;entorno léxico&lt;/em&gt; de la función interna guarda el valor de &lt;code&gt;5&lt;/code&gt;, que fue el que se le mandó como argumento al parámetro &lt;code&gt;factor&lt;/code&gt;, mientras que en la declaración &lt;code&gt;const _7x = crearTablaDeMultiplicar(7)&lt;/code&gt;, el &lt;em&gt;entorno léxico&lt;/em&gt; guarda el valor de &lt;code&gt;7&lt;/code&gt;, pues ese fue el valor que se envió como argumento al parámetro &lt;code&gt;factor&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejemplo de uso con HTML
&lt;/h3&gt;

&lt;p&gt;Imaginemos que tenemos estos elementos HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"size-12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;12&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"size-14"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;14&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"size-16"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;16&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La finalidad de estos botones es que al presionarlos cambien el tamaño de la fuente según corresponda, hay muchas formas en las que podríamos abordar este problema, sin embargo, en esta ocasión intentaremos resolverlo con closures, vemos el siguiente código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makeSizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setSize12&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeSizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setSize14&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeSizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setSize16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeSizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En la función &lt;code&gt;makeSizer&lt;/code&gt;, como podemos ver, se forma un closure, puesto que en la función interna se hace referencia al parámetro &lt;code&gt;size&lt;/code&gt; que nos llega en la función padre. Con esto podemos ver que la función &lt;code&gt;setSize12&lt;/code&gt; guarda en su &lt;em&gt;entorno léxico&lt;/em&gt; el valor de &lt;code&gt;12&lt;/code&gt;, por lo que al ejecutar esta función el tamaño de fuente del &lt;em&gt;body&lt;/em&gt; se cambiará a &lt;code&gt;12px&lt;/code&gt;, lo mismo pasará con las funciones &lt;code&gt;setSize14&lt;/code&gt; y &lt;code&gt;setSize16&lt;/code&gt; con los valores &lt;code&gt;14px&lt;/code&gt; y &lt;code&gt;16px&lt;/code&gt; respectivamente.&lt;/p&gt;

&lt;p&gt;Ahora podemos &lt;em&gt;"bindear"&lt;/em&gt; estas funciones en los eventos &lt;code&gt;onclick&lt;/code&gt; de los botones de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;size-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;size12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;size-14&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;size14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;size-16&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;size16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo, las closures nos ayudaron a crear una fábrica de funciones y poder reutilizar nuestra lógica para distintos valores.&lt;/p&gt;

&lt;h3&gt;
  
  
  Propiedades privadas con ayuda de closures
&lt;/h3&gt;

&lt;p&gt;En lenguajes cuyo paradigma es la programación orientada a objetos(POO), se pueden crear propiedades privadas, lo que significa que no se puede acceder a ellas más que dentro de la propia clase.&lt;/p&gt;

&lt;p&gt;Antes de ES6 no existían las clases en JavaScript, una forma que se usaba como &lt;em&gt;workaround&lt;/em&gt; es emular estas propiedades privadas creando closures, un ejemplo lo podemos ver a continuación, este ejemplo usa el &lt;em&gt;patrón de diseño de módulo&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;privateCounter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;changeBy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;privateCounter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;changeBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;changeBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;getCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;privateCounter&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})()&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCounter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCounter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCounter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privateCounter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como podemos observar, en este ejemplo estamos usando una IIFE(&lt;em&gt;Immediately Invoked Function Expression&lt;/em&gt;), lo que hace que en la constante &lt;code&gt;counter&lt;/code&gt; se guarde &lt;em&gt;"en automático"&lt;/em&gt; lo que retorna esta función. Con este ejemplo podemos ver que realmente las closures no solo son &lt;em&gt;"funciones que retornan otras funciones..."&lt;/em&gt;, sino que como vemos, estamos retornando un objeto con distintos métodos que a través de las closures mantienen viva la referencia a la variable &lt;code&gt;privateCounter&lt;/code&gt; y a la constante &lt;code&gt;changeBy&lt;/code&gt;, que a su vez internamente crea también una closure con la variable &lt;code&gt;privateCounter&lt;/code&gt; y como podemos observar en la última línea, no podemos acceder directamente a &lt;code&gt;privateCounter&lt;/code&gt;, sólo a través de la función &lt;code&gt;getCounter&lt;/code&gt;, así, emulamos comportamientos de la POO, como el encapsulamiento, con ayuda de las closures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closures sobre módulos
&lt;/h3&gt;

&lt;p&gt;Las closures también pueden generarse en distintos módulos, por ejemplo veamos lo siguiente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// fooModule.js&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getFoo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setFoo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este módulo crea un par de funciones &lt;em&gt;setter&lt;/em&gt; y &lt;em&gt;getter&lt;/em&gt; sobre la variable &lt;code&gt;foo&lt;/code&gt;, lo que hace que aunque esta variable no sea accesible desde otros módulos, porque no está exportada, sí pueda ser alcanzada y modificada a través de las funciones &lt;code&gt;getFoo&lt;/code&gt; y &lt;code&gt;setFoo&lt;/code&gt;, que como podemos ver, han creado un closure con la variable &lt;code&gt;foo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getFoo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFoo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./fooModule.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getFoo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="nf"&gt;setFoo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getFoo&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Las closures también pueden ser creadas sobre valores importados y que se consideren &lt;em&gt;"enlazados en vivo"&lt;/em&gt;, ya que al cambiar el valor original cambia el valor importado en consecuencia, esto también es gracias a que los módulos en JavaScript se crean como un &lt;em&gt;singleton&lt;/em&gt;, es decir, en todos los lugares donde se importe el módulo, realmente se estará usando la misma instancia del mismo,&lt;br&gt;
veamos el siguiente ejemplo para comprenderlo mejor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// barModule.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// closureCreator.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./barModule.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Se crea el closure sobre un enlace en vivo importado&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getBar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getBar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./closureCreator.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setBar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./barModule.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getBar&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nf"&gt;setBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getBar&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este ejemplo vemos que la variable &lt;code&gt;bar&lt;/code&gt; se crea en &lt;code&gt;barModule.js&lt;/code&gt;, y en este mismo módulo se exporta la función &lt;code&gt;setBar&lt;/code&gt; para poder cambiar su valor; en el módulo &lt;code&gt;closureCreator.js&lt;/code&gt; se crea el closure dentro de la función &lt;code&gt;getBar&lt;/code&gt; y estas dos funciones exportadas por módulos distintos pueden ser usadas en un tercer módulo &lt;code&gt;index.js&lt;/code&gt;, y al modificar la variable con la función &lt;code&gt;setBar&lt;/code&gt; y volver a ejecutar la función &lt;code&gt;getBar&lt;/code&gt;, podemos ver que el valor original de &lt;code&gt;bar&lt;/code&gt; ha cambiado y la función &lt;code&gt;getBar&lt;/code&gt; tiene acceso al nuevo valor actualizado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cadena de alcance de las closures
&lt;/h2&gt;

&lt;p&gt;Gracias al &lt;em&gt;entorno léxico&lt;/em&gt; que existe dentro de cada función cada vez que se crea una, los bloques anidados pueden acceder hasta las variables que estén en &lt;em&gt;entornos léxicos&lt;/em&gt; de niveles superiores, miremos el siguiente ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hija&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;padre&lt;/span&gt;&lt;span class="p"&gt;()()&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que pasa en este ejemplo es lo siguiente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se declara la constante &lt;code&gt;globalValue&lt;/code&gt; en el &lt;em&gt;entorno léxico&lt;/em&gt; global.&lt;/li&gt;
&lt;li&gt;La función &lt;code&gt;padre&lt;/code&gt; guarda en su &lt;em&gt;entorno léxico&lt;/em&gt; dos cosas, el &lt;em&gt;registro de entorno&lt;/em&gt;(que en este caso está vacío porque no hay
variables ni parámetros locales de la función &lt;code&gt;padre&lt;/code&gt;) y la referencia al &lt;em&gt;entorno léxico&lt;/em&gt; externo, que en este caso es el
&lt;em&gt;entorno léxico&lt;/em&gt; global.&lt;/li&gt;
&lt;li&gt;Dentro de la función &lt;code&gt;padre&lt;/code&gt; se crea una nueva función, la función &lt;code&gt;hija&lt;/code&gt;, esta función también tiene su propio &lt;em&gt;entorno léxico&lt;/em&gt;,
que al igual que la función &lt;code&gt;padre&lt;/code&gt;, tiene el &lt;em&gt;registro de entorno&lt;/em&gt;, que también está vacío al no haber variables ni parámetros
en el ámbito local de la función &lt;code&gt;hija&lt;/code&gt;, y la referencia al &lt;em&gt;entorno léxico&lt;/em&gt; superior, que es el de la función &lt;code&gt;padre&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Dentro de la función &lt;code&gt;hija&lt;/code&gt; se intente leer la variable &lt;code&gt;globalValue&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;JavaScript primero mira en el &lt;em&gt;registro de entorno&lt;/em&gt; de la propia función &lt;code&gt;hija&lt;/code&gt;, como no la encuentra, usa la referencia externa
guardada dentro de su &lt;em&gt;entorno léxico&lt;/em&gt; para acceder al &lt;em&gt;entorno léxico&lt;/em&gt; de la función &lt;code&gt;padre&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Busca la variable &lt;code&gt;globalValue&lt;/code&gt; en el &lt;em&gt;registro de entorno&lt;/em&gt; de la función &lt;code&gt;padre&lt;/code&gt; pero tampoco la encuentra ahí, así que usa la
referencia externa que tiene el &lt;em&gt;entorno léxico&lt;/em&gt; de la función &lt;code&gt;padre&lt;/code&gt; para acceder al siguiente nivel, que en nuestro ejemplo
es el &lt;em&gt;entorno léxico global&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Al llegar al &lt;em&gt;entorno léxico global&lt;/em&gt;, busca en el &lt;em&gt;registro de entorno&lt;/em&gt; de este &lt;em&gt;entono léxico&lt;/em&gt; la variable &lt;code&gt;globalValue&lt;/code&gt;, en
este &lt;em&gt;registro de entorno&lt;/em&gt; sí existe, por lo que accede a ela, lee su valor y opera con el mismo, en nuestro ejemplo simplemente
muestra el valor guardado en la consola.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es de esta manera como las funciones o bloques que están muy anidados pueden llegar a leer variables que se encuentren en &lt;em&gt;registros de entorno&lt;/em&gt; de niveles superiores. Un modelo mental que podemos tener al momento de intentar entender este comportamiento es mirarlo como una lista simplemente enlazada(&lt;em&gt;single linked list&lt;/em&gt;), cuyos valores se van enlazando desde el bloque más anidado&lt;br&gt;
hasta el de nivel superior.&lt;/p&gt;

&lt;p&gt;Algo que me ayudó a comprender cómo estos valores se van enlazando es viéndolo de la siguiente manera, en nuestro ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entornoLexicoDeFuncionHija&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// vacío porque no hay variables ni parámetros declarados en la función hija&lt;/span&gt;
  &lt;span class="na"&gt;registroDeEntorno&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;

  &lt;span class="c1"&gt;// referencia al entorno léxico de la función padre&lt;/span&gt;
  &lt;span class="na"&gt;referenciaExterna&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// vacío porque no hay variables ni parámetros declarados en la función padre&lt;/span&gt;
    &lt;span class="na"&gt;registroDeEntorno&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;

    &lt;span class="c1"&gt;// referencia al entorno léxico global&lt;/span&gt;
    &lt;span class="na"&gt;referenciaExterna&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// en este entorno léxico si está declarada la variable globalValue&lt;/span&gt;
      &lt;span class="na"&gt;registroDeEntorno&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;globalValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;

      &lt;span class="na"&gt;referenciaExterna&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="c1"&gt;// ya no hay porque este es el entorno léxico global&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aunque esto es un resumen muy abstracto de cómo se van enlazando los &lt;em&gt;entornos léxicos&lt;/em&gt;, puede ayudarnos a comprender cómo es que desde funciones o bloques muy anidados JavaScript puede acceder a variables de entornos superiores.&lt;/p&gt;

&lt;p&gt;De manera general y resumida podemos decir que cada bloque tiene 3 alcances:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El alcance local (Registro de Entorno)&lt;/li&gt;
&lt;li&gt;El alcance adyacente o envolvente (a través de las referencias externas del &lt;em&gt;entorno léxico&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;El alcance global (gracias a los enlaces que existen en los &lt;em&gt;entornos léxicos&lt;/em&gt; adyacentes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto mismo es lo que pasa cuando tenemos muchas closures anidadas de la siguiente manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;suma&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// 20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gracias a los &lt;em&gt;entornos léxicos&lt;/em&gt; enlazados es que la función &lt;code&gt;sum3&lt;/code&gt; puede acceder y leer todos los valores de &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, &lt;code&gt;c&lt;/code&gt;, &lt;code&gt;d&lt;/code&gt; y &lt;code&gt;e&lt;/code&gt;, a esto es a lo que se conoce como &lt;strong&gt;&lt;em&gt;cadena de alcance de las closures&lt;/em&gt;&lt;/strong&gt;, lo cual ahora ya sabemos por qué funciona.&lt;/p&gt;

&lt;p&gt;Como dato adicional, la expresión que escribimos en el ejemplo anterior &lt;code&gt;suma(1)(2)(3)(4)&lt;/code&gt; está usando una técnica que se llama &lt;strong&gt;&lt;em&gt;Currying&lt;/em&gt;&lt;/strong&gt;, la cual, en JavaScript, también depende de las closures para poder funcionar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recomendaciones y buenas prácticas al usar closures
&lt;/h2&gt;

&lt;p&gt;Aunque las closures son una característica poderosa y nos pueden ayudar a resolver varios problemas, es necesario tener en cuenta algunas recomendaciones y buenas prácticas al usarlas, recuerda, un gran poder conlleva una gran responsabilidad.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privatizar datos y variables&lt;/strong&gt;: Usa closures para ocultar variables del alcance global. Esto evita que otros scripts modifiquen
tus datos accidentalmente. Define variables dentro de una función y expón solo los métodos para interactuar con ellas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evitar fugas de memoria(Memory Leaks)&lt;/strong&gt;: Los closures mantienen vivas las variables de su entorno externo, lo que puede impedir
que el recolector de basura libere esa memoria. Limpia las referencias asignando &lt;code&gt;null&lt;/code&gt; o &lt;code&gt;undefined&lt;/code&gt; a las variables o funciones
que ya no vayas a utilizar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crear fábricas de funciones(Factory Functions)&lt;/strong&gt;: Aprovecha los closures para generar funciones personalizadas basadas en
argumentos iniciales. Esto promueve la reutilización de código. Pasa un parámetro a la función principal para configurar el entorno
y retorna una nueva función adaptada.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantener la legibilidad y evitar el abuso&lt;/strong&gt;: Anidar demasiados closures puede hacer que el código sea difícil de leer, depurar
y mantener. Usa closures cuando aporten un beneficio claro(como el encapsulamiento), no por defecto en cada función.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cierre
&lt;/h2&gt;

&lt;p&gt;Ahora ya conoces realmente lo que son las closures y cómo funciona a más bajo nivel esta característica del lenguaje JavaScript, sin embargo, no significa que ahora tengas que usar closures en todas partes, siempre ten en mente que cada nuevo concepto que aprendemos es una herramienta nueva que agregamos a nuestro arsenal, de esta manera, cuando estemos resolviendo un problema sepamos que esa herramienta existe y podemos hacer uso de ella para llegar a algunas soluciones si es necesario, aunque también siempre recuerda que es nuestra labor y responsabilidad como ingenieros de software saber cuando sí usar una herramienta y cuando no, así como las ventajas y desventajas frente a otras posibles soluciones con otras herramientas distintas.&lt;/p&gt;

&lt;p&gt;Espero que este artículo te haya gustado y hayas aprendido algo nuevo, sin más me despido, nos vemos en la próxima entrega.&lt;/p&gt;

&lt;p&gt;-&lt;br&gt;
Post escrito por Pedro Midueño, puedes conocer más de mí en &lt;a href="https://pemid.dev" rel="noopener noreferrer"&gt;pemid.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>spanish</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
