Cierre en JavaScript

La mayoría de los desarrolladores de JavaScript usan el cierre consciente o inconscientemente. Incluso si lo hacen inconscientemente, funciona bien en la mayoría de los casos. Pero conocer el cierre proporcionará un mejor control sobre el código al usarlos. Y otra razón para aprender el cierre es que es la pregunta más frecuente en la entrevista para los desarrolladores de JavaScript. 
Requisito previo : Ámbito variable en JavaScript 

Veamos y entendamos el cierre a través de un ejemplo. 

Ejemplo 1: 

Javascript

// Explanation of closure
/* 1 */        function foo()
/* 2 */         {
/* 3 */             var b = 1;
/* 4 */             function inner(){
/* 5 */                 return b;
/* 6 */             }
/* 7 */             return inner;
/* 8 */         }
/* 9 */         var get_func_inner = foo();        
 
/* 10 */         console.log(get_func_inner());
/* 11 */         console.log(get_func_inner());
/* 12 */         console.log(get_func_inner());

Explicación: Lo interesante a tener en cuenta aquí es desde la línea número 9 hasta la línea número 12 . En la línea número 9 hemos terminado con la ejecución de la función foo() y todo el cuerpo de la función inner() se devuelve y se almacena en var get_func_inner , debido a la línea 7 return inner
[La declaración de retorno no ejecuta la función interna: la función se ejecuta solo cuando va seguida de(), sino que la declaración de retorno devuelve la referencia a la función como una función en JavaScript también es un objeto.]

Podemos acceder a la variable b que se define en la función foo() a través de la función inner() ya que la última conserva la string de alcance de la función envolvente en el momento de la ejecución de la función envolvente, es decir, la función interna conoce el valor de b a través de su string de alcance . 
Este es el cierre en acción, es decir, la función interna puede tener acceso a las variables de la función externa, así como a todas las variables globales. 
Salida del código anterior: 

Output_example_1

Para ver la variable y la función vinculadas dentro del cierre, podemos escribir como:  

Javascript

/* 13 */         console.dir(get_func_inner);

Producción: 

Output_dir_for_function

Como podemos ver las variables dentro del cierre en la sección de alcance.

Definición de cierre: 

En los lenguajes de programación, los cierres (también cierres léxicos o cierres de funciones) son técnicas para implementar enlaces de nombres con alcance léxico en lenguajes con funciones de primera clase. Operacionalmente, un cierre es un registro que almacena una función[a] junto con un entorno:[1] un mapeo que asocia cada variable libre de la función (variables que se usan localmente, pero definidas en un ámbito envolvente) con el valor o referencia a cuyo nombre estaba vinculado cuando se creó el cierre.[b] 
-Wikipedia

 o 

En otras palabras, el cierre se crea cuando una función secundaria mantiene el entorno del ámbito principal incluso después de que la función principal ya se haya ejecutado. 

Nota: El cierre es el concepto de función + entorno léxico en el que se creó la función. por lo tanto, cada función declarada dentro de otra función tiene acceso a la string de alcance de la función externa y las variables creadas dentro del alcance de la función externa no se destruirán.

Ahora veamos el otro ejemplo. 

Ejemplo 2:  

Javascript

function foo(outer_arg) {
 
    function inner(inner_arg) {
        return outer_arg + inner_arg;
    }
    return inner;
}
var get_func_inner = foo(5);
 
console.log(get_func_inner(4));
console.log(get_func_inner(3));

Explicación: En el ejemplo anterior, usamos una función de parámetro en lugar de una predeterminada. Tenga en cuenta que incluso cuando hayamos terminado con la ejecución de foo(5) , podemos acceder a la variable outside_arg desde la función interna. Y en la ejecución de la función interna, produzca la suma de exterior_arg e interior_arg como se desee. 

Producción:  

Ouput_example2

Ahora veamos un ejemplo de cierre dentro de un bucle. 
En este ejemplo almacenaríamos una función anónima en cada índice de una array. 

Ejemplo 3:  

Javascript

// Outer function
function outer()
{
    var arr = [];
    var i;
    for (i = 0; i < 4; i++)
    {
        // storing anonymous function
        arr[i] = function () { return i; }
    }
 
    // returning the array.
    return arr;
}
 
var get_arr = outer();
 
console.log(get_arr[0]());
console.log(get_arr[1]());
console.log(get_arr[2]());
console.log(get_arr[3]());

Producción: 

Ouput_example_3

Explicación: ¿Adivinaste la respuesta correcta? En el código anterior, hemos creado cuatro cierres que apuntan a la variable i, que es una variable local de la función externa. El cierre no recuerda el valor de la variable, solo apunta a la variable o almacena la referencia de la variable y, por lo tanto, devuelve el valor actual. En el código anterior, cuando intentamos actualizar, el valor se refleja en todos porque el cierre almacena la referencia. 

Veamos una forma correcta de escribir el código anterior para obtener diferentes valores de i en diferentes índices. 

Ejemplo 4:  

Javascript

// Outer function
function outer()
{
    function create_Closure(val)
    {
        return function()
        {
            return val;
        }
    }
    var arr = [];
    var i;
    for (i = 0; i < 4; i++)
    {
        arr[i] = create_Closure(i);
    }
    return arr;
}
var get_arr = outer();
console.log(get_arr[0]());
console.log(get_arr[1]());
console.log(get_arr[2]());
console.log(get_arr[3]());

Producción: 

Ouput_example3_modified

Explicación: en el código anterior, estamos actualizando el argumento de la función create_Closure con cada llamada. Por lo tanto, obtenemos diferentes valores de i en diferentes índices.

Nota: puede ser un poco difícil obtener el concepto de cierre a la vez, pero intente experimentar con el cierre en diferentes escenarios, como para crear getter/setter, devoluciones de llamada, etc. 

Referencia: 
«JavaScript orientado a objetos» por Stoyan Stefanov 
Este artículo es una contribución de Sumit Ghosh . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *