Pregunta

Hice una pregunta sobre Currying y se mencionaron cierres.¿Qué es un cierre?¿Cómo se relaciona con el curry?

¿Fue útil?

Solución

Alcance variable

Cuando declaras una variable local, esa variable tiene un alcance.Generalmente, las variables locales existen sólo dentro del bloque o función en el que las declaras.

function() {
  var a = 1;
  console.log(a); // works
}    
console.log(a); // fails

Si intento acceder a una variable local, la mayoría de los idiomas la buscarán en el ámbito actual y luego a través de los ámbitos principales hasta llegar al ámbito raíz.

var a = 1;
function() {
  console.log(a); // works
}    
console.log(a); // works

Cuando se termina un bloque o función, sus variables locales ya no son necesarias y generalmente se agotan en la memoria.

Así es como normalmente esperamos que funcionen las cosas.

Un cierre es un alcance de variable local persistente.

Un cierre es un alcance persistente que retiene las variables locales incluso después de que la ejecución del código haya salido de ese bloque.Los lenguajes que admiten el cierre (como JavaScript, Swift y Ruby) le permitirán mantener una referencia a un ámbito (incluidos sus ámbitos principales), incluso después de que el bloque en el que se declararon esas variables haya terminado de ejecutarse, siempre que mantenga una referencia. a ese bloque o función en alguna parte.

El objeto de alcance y todas sus variables locales están vinculados a la función y persistirán mientras esa función persista.

Esto nos da portabilidad de funciones.Podemos esperar que cualquier variable que estuviera dentro del alcance cuando se definió la función por primera vez todavía esté dentro del alcance cuando llamemos a la función más tarde, incluso si llamamos a la función en un contexto completamente diferente.

Por ejemplo

Aquí hay un ejemplo realmente simple en JavaScript que ilustra este punto:

outer = function() {
  var a = 1;
  var inner = function() {
    console.log(a);
  }
  return inner; // this returns a function
}

var fnc = outer(); // execute outer to get inner 
fnc();

Aquí he definido una función dentro de una función.La función interna obtiene acceso a todas las variables locales de la función externa, incluidas a.La variable a está dentro del alcance de la función interna.

Normalmente, cuando una función sale, todas sus variables locales desaparecen.Sin embargo, si devolvemos la función interna y la asignamos a una variable fnc para que persista después outer ha salido, todas las variables que estaban dentro del alcance cuando inner fue definido también persistir.La variable a ha sido cerrado, está dentro de un cierre.

Tenga en cuenta que la variable a es totalmente privado para fnc.Esta es una forma de crear variables privadas en un lenguaje de programación funcional como JavaScript.

Como podrás adivinar, cuando llamo fnc() imprime el valor de a, que es "1".

En un lenguaje sin cierre, la variable a habría sido basura recolectada y desechada cuando la función outer salió.Llamar a fnc habría arrojado un error porque a ya no existe.

En JavaScript, la variable a persiste porque el alcance de la variable se crea cuando la función se declara por primera vez y persiste mientras la función continúe existiendo.

a pertenece al ámbito de outer.El alcance de inner tiene un puntero principal al alcance de outer. fnc es una variable que apunta a inner. a persiste mientras fnc persiste. a está dentro del cierre.

Otros consejos

Daré un ejemplo (en JavaScript):

function makeCounter () {
  var count = 0;
  return function () {
    count += 1;
    return count;
  }
}

var x = makeCounter();

x(); returns 1

x(); returns 2

...etc...

Lo que hace esta función, makeCounter, es devolver una función, que hemos llamado x, que contará de uno en uno cada vez que se llame.Como no proporcionamos ningún parámetro para x, de alguna manera debe recordar el recuento.Sabe dónde encontrarlo basándose en lo que se llama alcance léxico: debe buscar el lugar donde está definido para encontrar el valor.Este valor "oculto" es lo que se llama cierre.

Aquí está mi ejemplo de curry nuevamente:

function add (a) {
  return function (b) {
    return a + b;
  }
}

var add3 = add(3);

add3(4); returns 7

Lo que puedes ver es que cuando llamas a add con el parámetro a (que es 3), ese valor está contenido en el cierre de la función devuelta que estamos definiendo como add3.De esa manera, cuando llamamos a add3, sabe dónde encontrar el valor a para realizar la suma.

la respuesta de kyle es bastante bueno.Creo que la única aclaración adicional es que el cierre es básicamente una instantánea de la pila en el punto en que se crea la función lambda.Luego, cuando la función se vuelve a ejecutar, la pila se restaura a ese estado antes de ejecutar la función.Así, como menciona Kyle, ese valor oculto (count) está disponible cuando se ejecuta la función lambda.

En primer lugar, al contrario de lo que dice la mayoría de la gente aquí, el cierre es no Una función!Así que lo que es ¿él?
Es un colocar de símbolos definidos en el "contexto circundante" de una función (conocido como su ambiente) que la convierten en una expresión CERRADA (es decir, una expresión en la que cada símbolo está definido y tiene un valor, por lo que puede evaluarse).

Por ejemplo, cuando tienes una función de JavaScript:

function closed(x) {
  return x + 3;
}

es un expresión cerrada porque todos los símbolos que aparecen en él están definidos en él (sus significados son claros), por lo que puedes evaluarlo.En otras palabras, es autónomo.

Pero si tienes una función como esta:

function open(x) {
  return x*y + 3;
}

es un expresión abierta porque hay símbolos en él que no han sido definidos en él.A saber, y.Al observar esta función, no podemos decir qué y es y qué significa, no sabemos su valor, por lo que no podemos evaluar esta expresión.Es decir.No podemos llamar a esta función hasta que sepamos qué y se supone que significa en él.Este y se llama un variable libre.

Este y pide una definición, pero esta definición no es parte de la función: se define en otro lugar, en su "contexto circundante" (también conocido como el ambiente).Al menos eso es lo que esperamos :P

Por ejemplo, podría definirse globalmente:

var y = 7;

function open(x) {
  return x*y + 3;
}

O podría definirse en una función que lo envuelva:

var global = 2;

function wrapper(y) {
   var w = "unused";

   return function(x) {
     return x*y + 3;
   }

}

La parte del entorno que da significado a las variables libres de una expresión es la cierre.Se llama así porque se convierte en un abierto expresión en una cerrado uno, proporcionando estas definiciones faltantes para todos sus variables libres, para que podamos evaluarlo.

En el ejemplo anterior, la función interna (a la que no le dimos un nombre porque no la necesitábamos) es una expresión abierta porque la variable y en ello esta gratis – su definición está fuera de la función, en la función que la envuelve.El ambiente para esa función anónima es el conjunto de variables:

{
  global: 2,
  w: "unused",
  y: [whatever has been passed to that wrapper function as its parameter `y`]
}

Ahora el cierre es esa parte de este ambiente que cierra la función interna proporcionando las definiciones para todos sus variables libres.En nuestro caso, la única variable libre en la función interna era y, entonces el cierre de esa función es este subconjunto de su entorno:

{
  y: [whatever has been passed to that wrapper function as its parameter `y`]
}

Los otros dos símbolos definidos en el entorno son no parte de cierre de esa función, porque no requiere que se ejecuten.No son necesarios para cerca él.

Más sobre la teoría detrás de esto aquí:https://stackoverflow.com/a/36878651/434562

Vale la pena señalar que en el ejemplo anterior, la función contenedora devuelve su función interna como un valor.El momento en que llamamos a esta función puede ser remoto en el tiempo desde el momento en que se ha definido (o creado) la función.En particular, su función de ajuste ya no se está ejecutando y sus parámetros que estaban en la pila de llamadas ya no están ahí :P Esto crea un problema, porque la función interna necesita y ¡Estar allí cuando sea llamado!En otras palabras, requiere que las variables de su cierre de alguna manera sobrevivir a la función contenedora y estar allí cuando sea necesario.Por lo tanto, la función interna tiene que hacer una instantánea de estas variables las cuales hacen su cierre y las guardan en algún lugar seguro para su uso posterior.(En algún lugar fuera de la pila de llamadas).

Y es por eso que la gente a menudo confunde el término cierre ser ese tipo especial de función que puede hacer instantáneas de las variables externas que usan, o la estructura de datos utilizada para almacenar estas variables para más adelante.Pero espero que entiendas ahora que son no el cierre en sí: son sólo formas de implementar cierres en un lenguaje de programación, o mecanismos de lenguaje que permiten que las variables del cierre de la función estén ahí cuando sea necesario.Hay muchos conceptos erróneos sobre los cierres que (innecesariamente) hacen que este tema sea mucho más confuso y complicado de lo que realmente es.

Un cierre es una función que puede hacer referencia al estado en otra función.Por ejemplo, en Python, esto usa el cierre "interior":

def outer (a):
    b = "variable in outer()"
    def inner (c):
        print a, b, c
    return inner

# Now the return value from outer() can be saved for later
func = outer ("test")
func (1) # prints "test variable in outer() 1

Para ayudar a facilitar la comprensión de los cierres, podría ser útil examinar cómo podrían implementarse en un lenguaje procesal.Esta explicación seguirá una implementación simplista de cierres en Scheme.

Para empezar, debo introducir el concepto de espacio de nombres.Cuando ingresa un comando en un intérprete de esquema, este debe evaluar los distintos símbolos en la expresión y obtener su valor.Ejemplo:

(define x 3)

(define y 4)

(+ x y) returns 7

Las expresiones definidas almacenan el valor 3 en el lugar para x y el valor 4 en el lugar para y.Luego, cuando llamamos (+ x y), el intérprete busca los valores en el espacio de nombres y puede realizar la operación y devolver 7.

Sin embargo, en Scheme hay expresiones que le permiten anular temporalmente el valor de un símbolo.He aquí un ejemplo:

(define x 3)

(define y 4)

(let ((x 5))
   (+ x y)) returns 9

x returns 3

Lo que hace la palabra clave let es introducir un nuevo espacio de nombres con x como valor 5.Notarás que aún puedes ver que y es 4, por lo que la suma devuelta es 9.También puedes ver que una vez que la expresión termina, x vuelve a ser 3.En este sentido, x ha quedado temporalmente enmascarado por el valor local.

Los lenguajes procedimentales y orientados a objetos tienen un concepto similar.Siempre que declaras una variable en una función que tiene el mismo nombre que una variable global, obtienes el mismo efecto.

¿Cómo implementaríamos esto?Una forma sencilla es con una lista vinculada: el encabezado contiene el nuevo valor y el final contiene el espacio de nombres anterior.Cuando necesite buscar un símbolo, comience por la cabeza y avance hasta la cola.

Ahora pasemos por el momento a la implementación de funciones de primera clase.Más o menos, una función es un conjunto de instrucciones que se ejecutan cuando se llama a la función y culminan en el valor de retorno.Cuando leemos una función, podemos almacenar estas instrucciones detrás de escena y ejecutarlas cuando se llama a la función.

(define x 3)

(define (plus-x y)
  (+ x y))

(let ((x 5))
  (plus-x 4)) returns ?

Definimos x como 3 y más-x como su parámetro, y, más el valor de x.Finalmente llamamos plus-x en un entorno donde x ha sido enmascarado por una nueva x, ésta con valor 5.Si simplemente almacenamos la operación, (+ x y), para la función más-x, dado que estamos en el contexto de que x es 5, el resultado devuelto sería 9.Esto es lo que se llama alcance dinámico.

Sin embargo, Scheme, Common Lisp y muchos otros lenguajes tienen lo que se llama alcance léxico: además de almacenar la operación (+ x y), también almacenamos el espacio de nombres en ese punto en particular.De esa manera, cuando buscamos los valores podemos ver que x, en este contexto, es realmente 3.Este es un cierre.

(define x 3)

(define (plus-x y)
  (+ x y))

(let ((x 5))
  (plus-x 4)) returns 7

En resumen, podemos usar una lista vinculada para almacenar el estado del espacio de nombres en el momento de la definición de la función, lo que nos permite acceder a variables desde ámbitos adjuntos, además de brindarnos la capacidad de enmascarar localmente una variable sin afectar el resto del programa.

Aquí hay un ejemplo del mundo real de por qué los cierres patean traseros...Esto está sacado directamente de mi código Javascript.Permítanme ilustrar.

Function.prototype.delay = function(ms /*[, arg...]*/) {
  var fn = this,
      args = Array.prototype.slice.call(arguments, 1);

  return window.setTimeout(function() {
      return fn.apply(fn, args);
  }, ms);
};

Y así es como lo usarías:

var startPlayback = function(track) {
  Player.play(track);  
};
startPlayback(someTrack);

Ahora imagina que quieres que la reproducción comience retrasada, como por ejemplo 5 segundos después de que se ejecute este fragmento de código.Bueno, eso es fácil con delay y su cierre:

startPlayback.delay(5000, someTrack);
// Keep going, do other things

Cuando usted llama delay con 5000ms, se ejecuta el primer fragmento y almacena los argumentos pasados ​​en su cierre.Luego, 5 segundos más tarde, cuando el setTimeout Cuando ocurre una devolución de llamada, el cierre aún mantiene esas variables, por lo que puede llamar a la función original con los parámetros originales.
Este es un tipo de curry o decoración funcional.

Sin cierres, tendría que mantener de alguna manera el estado de esas variables fuera de la función, llenando así el código fuera de la función con algo que lógicamente pertenece dentro de ella.El uso de cierres puede mejorar enormemente la calidad y legibilidad de su código.

tl; dr

Un cierre es una función y su alcance asignado (o utilizado como) una variable.Así, el cierre del nombre:el alcance y la función se incluyen y se utilizan como cualquier otra entidad.

Explicación detallada al estilo de Wikipedia.

Según Wikipedia, un cierre es:

Técnicas para implementar la vinculación de nombres con ámbito léxico en idiomas con funciones de primera clase.

¿Qué significa eso?Veamos algunas definiciones.

Explicaré los cierres y otras definiciones relacionadas usando este ejemplo:

function startAt(x) {
    return function (y) {
        return x + y;
    }
}

var closure1 = startAt(1);
var closure2 = startAt(5);

console.log(closure1(3)); // 4 (x == 1, y == 3)
console.log(closure2(3)); // 8 (x == 5, y == 3)

Funciones de primera clase

Básicamente eso significa Podemos usar funciones como cualquier otra entidad..Podemos modificarlos, pasarlos como argumentos, devolverlos de funciones o asignarlos por variables.Técnicamente hablando, son ciudadanos de primera clase, de ahí el nombre:funciones de primera clase.

En el ejemplo anterior, startAt devuelve un (anónimo) función a qué función se le asigna closure1 y closure2.Como puede ver, JavaScript trata las funciones como cualquier otra entidad (ciudadanos de primera clase).

Enlace de nombre

Enlace de nombre se trata de descubrir que dato una variable (identificador) referencias.El alcance es realmente importante aquí, ya que es lo que determinará cómo se resuelve una vinculación.

En el ejemplo anterior:

  • En el alcance de la función anónima interna, y está obligado a 3.
  • En startAtel alcance, x está obligado a 1 o 5 (dependiendo del cierre).

Dentro del alcance de la función anónima, x no está vinculado a ningún valor, por lo que debe resolverse en una parte superior (startAt's) alcance.

Alcance léxico

Como Wikipedia dice, el alcance:

Es la región de un programa informático donde la vinculación es válida: donde el nombre puede usarse para referirse a la entidad.

Hay dos técnicas:

  • Alcance léxico (estático):La definición de una variable se resuelve buscando su bloque o función contenedora, luego, si eso falla, buscando el bloque contenedor externo, y así sucesivamente.
  • Alcance dinámico:Se busca la función que llama, luego la función que llamó a esa función que llama, y ​​así sucesivamente, avanzando hacia arriba en la pila de llamadas.

Para más explicaciones, mira esta pregunta y echa un vistazo a Wikipedia.

En el ejemplo anterior, podemos ver que JavaScript tiene un alcance léxico, porque cuando x se resuelve, el enlace se busca en la parte superior (startAt's) alcance, basado en el código fuente (la función anónima que busca x está definida dentro startAt) y no en función de la pila de llamadas, la forma (el alcance donde) se llamó la función.

Envolver (cerrar)

En nuestro ejemplo, cuando llamamos startAt, devolverá una función (de primera clase) que será asignada a closure1 y closure2 por lo tanto se crea un cierre, porque las variables pasadas 1 y 5 será salvo dentro startAtalcance, que se incluirá con la función anónima devuelta.Cuando llamamos a esta función anónima a través de closure1 y closure2 con el mismo argumento (3), El valor de y se encontrará inmediatamente (ya que ese es el parámetro de esa función), pero x no está vinculado al alcance de la función anónima, por lo que la resolución continúa en el alcance de la función (léxicamente) superior (que se guardó en el cierre) donde x se encuentra vinculado a cualquiera de los dos 1 o 5.Ahora sabemos todo lo relacionado con la suma, por lo que se puede devolver el resultado y luego imprimirlo.

Ahora deberías entender los cierres y cómo se comportan, que es una parte fundamental de JavaScript.

Zurra

Ah, y también aprendiste lo que zurra es sobre:usa funciones (cierres) para pasar cada argumento de una operación en lugar de usar una función con múltiples parámetros.

Las funciones que no contienen variables libres se llaman funciones puras.

Las funciones que contienen una o más variables libres se denominan cierres.

var pure = function pure(x){
  return x 
  // only own environment is used
}

var foo = "bar"

var closure = function closure(){
  return foo 
  // foo is a free variable from the outer environment
}

origen: https://leanpub.com/javascriptallongesix/read#leanpub-auto-if-functions- without-free-variables-are-pure-are-closures-impure

En una situación normal, las variables están sujetas a una regla de alcance:Las variables locales funcionan sólo dentro de la función definida.El cierre es una forma de romper esta regla temporalmente por conveniencia.

def n_times(a_thing)
  return lambda{|n| a_thing * n}
end

en el código anterior, lambda(|n| a_thing * n} es el cierre porque a_thing es referido por lambda (un creador de funciones anónimo).

Ahora, si coloca la función anónima resultante en una variable de función.

foo = n_times(4)

foo romperá la regla de alcance normal y comenzará a usar 4 internamente.

foo.call(3)

devuelve 12.

En resumen, el puntero de función es solo un puntero a una ubicación en la base del código del programa (como el contador del programa).Mientras Cierre = Puntero de función + Marco de pila.

.

Cierre es una característica en JavaScript donde una función tiene acceso a sus propias variables de alcance, acceso a las variables de función externas y acceso a las variables globales.

El cierre tiene acceso al alcance de su función externa incluso después de que la función externa haya regresado.Esto significa que un cierre puede recordar y acceder a variables y argumentos de su función externa incluso después de que la función haya finalizado.

La función interna puede acceder a las variables definidas en su propio alcance, el alcance de la función externa y el alcance global.Y la función externa puede acceder a la variable definida en su propio alcance y en el alcance global.

******************
Example of Closure
******************

var globalValue = 5;

function functOuter() 
{
    var outerFunctionValue = 10;

    //Inner function has access to the outer function value
    //and the global variables
    function functInner() 
    {
        var innerFunctionValue = 5;
        alert(globalValue+outerFunctionValue + innerFunctionValue);
    }
    functInner();
}
functOuter();

La salida será 20, cuya suma es la variable propia de la función interna, la variable de la función externa y el valor de la variable global.

Aquí hay otro ejemplo de la vida real y el uso de un lenguaje de programación popular en los juegos: Lua.Necesitaba cambiar ligeramente la forma en que funcionaba una función de biblioteca para evitar un problema de que la entrada estándar no estuviera disponible.

local old_dofile = dofile

function dofile( filename )
  if filename == nil then
    error( 'Can not use default of stdin.' )
  end

  old_dofile( filename )
end

El valor de old_dofile desaparece cuando este bloque de código finaliza su alcance (porque es local), sin embargo, el valor se ha incluido en un cierre, por lo que la nueva función dofile redefinida PUEDE acceder a él, o más bien una copia almacenada junto con la función como un 'valor añadido'.

De Lua.org:

Cuando una función se escribe encerrada en otra función, tiene acceso completo a las variables locales desde la función adjunta;esta característica se llama alcance léxico.Aunque pueda parecer obvio, no lo es.El alcance léxico, además de las funciones de primera clase, es un concepto poderoso en un lenguaje de programación, pero pocos lenguajes admiten ese concepto.

Si eres del mundo Java, puedes comparar un cierre con una función miembro de una clase.Mira este ejemplo

var f=function(){
  var a=7;
  var g=function(){
    return a;
  }
  return g;
}

La función g es un cierre: g cierra a en.Entonces g se puede comparar con una función miembro, a se puede comparar con un campo de clase, y la función f con una clase.

Cierres Siempre que tengamos una función definida dentro de otra función, la función interna tiene acceso a las variables declaradas en la función externa.Los cierres se explican mejor con ejemplos.En el Listado 2-18, puede ver que la función interna tiene acceso a una variable (VariableNouterFunction) desde el alcance externo.Las variables de la función externa han sido cerradas (o vinculadas) por la función interna.De ahí el término cierre.El concepto en sí es bastante simple y bastante intuitivo.

Listing 2-18:
    function outerFunction(arg) {
     var variableInOuterFunction = arg;

     function bar() {
             console.log(variableInOuterFunction); // Access a variable from the outer scope
     }
     // Call the local function to demonstrate that it has access to arg
     bar(); 
    }
    outerFunction('hello closure!'); // logs hello closure!

fuente: http://index-of.es/Varios/Basarat%20Ali%20Syed%20(auth.)-Beginning%20Node.js-Apress%20(2014).pdf

Eche un vistazo al siguiente código para comprender el cierre con mayor profundidad:

        for(var i=0; i< 5; i++){            
            setTimeout(function(){
                console.log(i);
            }, 1000);                        
        }

¿Aquí qué se producirá? 0,1,2,3,4 no eso será 5,5,5,5,5 debido al cierre

Entonces, ¿cómo se solucionará?La respuesta está a continuación:

       for(var i=0; i< 5; i++){
           (function(j){     //using IIFE           
                setTimeout(function(){
                               console.log(j);
                           },1000);
            })(i);          
        }

Permítanme explicarles de manera simple, cuando se creó una función, no sucedió nada hasta que llamó al bucle for en el primer código llamado 5 veces pero no se llamó inmediatamente, por lo que cuando llamó, es decir, después de 1 segundo y también esto es asíncrono, por lo que antes de que finalice este bucle for y almacene el valor 5 en var i y finalmente ejecutar setTimeout funcionar cinco veces e imprimir 5,5,5,5,5

Aquí cómo se resuelve usando IIFE, es decir, expresión de función de invocación inmediata

       (function(j){  //i is passed here           
            setTimeout(function(){
                           console.log(j);
                       },1000);
        })(i);  //look here it called immediate that is store i=0 for 1st loop, i=1 for 2nd loop, and so on and print 0,1,2,3,4

Para obtener más información, comprenda el contexto de ejecución para comprender el cierre.

  • Hay una solución más para resolver esto usando let (función ES6), pero bajo el capó la función anterior funciona

     for(let i=0; i< 5; i++){           
         setTimeout(function(){
                        console.log(i);
                    },1000);                        
     }
    
    Output: 0,1,2,3,4
    

=> Más explicación:

En la memoria, cuando el bucle for ejecuta la imagen, haga lo siguiente:

Bucle 1)

     setTimeout(function(){
                    console.log(i);
                },1000);  

Bucle 2)

     setTimeout(function(){
                    console.log(i);
                },1000); 

Bucle 3)

     setTimeout(function(){
                    console.log(i);
                },1000); 

Bucle 4)

     setTimeout(function(){
                    console.log(i);
                },1000); 

Bucle 5)

     setTimeout(function(){
                    console.log(i);
                },1000);  

Aquí no se ejecuta y luego, después de completar el ciclo, var i almacenó el valor 5 en la memoria, pero su alcance siempre es visible en su función secundaria, por lo que cuando la función se ejecuta dentro setTimeout sale cinco veces se imprime 5,5,5,5,5

entonces, para resolver este problema, utilice IIFE como se explica anteriormente.

Curry :Le permite evaluar parcialmente una función pasando solo un subconjunto de sus argumentos.Considera esto:

function multiply (x, y) {
  return x * y;
}

const double = multiply.bind(null, 2);

const eight = double(4);

eight == 8;

Cierre:Un cierre no es más que acceder a una variable fuera del alcance de una función.Es importante recordar que una función dentro de una función o una función anidada no es un cierre.Los cierres siempre se utilizan cuando es necesario acceder a variables fuera del alcance de la función.

function apple(x){
   function google(y,z) {
    console.log(x*y);
   }
   google(7,2);
}

apple(3);

// the answer here will be 21

El cierre es muy fácil.Podemos considerarlo de la siguiente manera:Cierre = función + su entorno léxico

Considere la siguiente función:

function init() {
    var name = “Mozilla”;
}

¿Cuál será el cierre en el caso anterior?Función init() y variables en su entorno léxico, es decir, nombre.Cierre = inicio() + nombre

Consideremos otra función:

function init() {
    var name = “Mozilla”;
    function displayName(){
        alert(name);
}
displayName();
}

¿Cuáles serán los cierres aquí?La función interna puede acceder a variables de la función externa.displayName() puede acceder al nombre de la variable declarada en la función principal, init().Sin embargo, se utilizarán las mismas variables locales en displayName() si existen.

Cierre 1 : función init + (nombre de variable + función displayName()) --> alcance léxico

Cierre 2 : función displayName + (nombre de variable) --> alcance léxico

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top