Traducción del entorno JavaScript, alcance léxico y cierres .Hablemos del medio ambiente. Nuestro enorme planeta es uno para todos. Durante la construcción de una nueva planta química, sería bueno aislarla para que todos los procesos internos no salgan de sus fronteras. Podemos decir que el ambiente y el microclima de esta planta están aislados del ambiente externo.
El programa está organizado de manera similar. Lo que crea externamente (funciones externas, sentencias condicionales, bucles y otros bloques) es un entorno externo y global.

La
age
constante, la función
multiplier
y la variable de
result
están en el entorno externo. Estos componentes tienen un alcance global. Un ámbito es el área en la que un componente está disponible.
En este caso,
x
es una constante dentro de la función
multiplier
. Como está dentro de un bloque de código, es una constante local, no global. Es visible solo dentro de la función, pero no fuera: su alcance es local.
La función
multiplier
tiene otro componente del ámbito local: este es el argumento
num
. Definirlo es más difícil que una constante o variable, pero se comporta más o menos como una variable local.
No tenemos acceso externo a
x
; no parece existir:

console.log
llamó a
x
en un entorno global en el que no está definido. Como resultado, obtuvimos un ReferenceError.
Podemos establecer
x
globalmente:

Tenemos una
x
global con un valor conocido, pero la
x
local en la función
multiplier
todavía es visible solo desde el interior. Estas
x
no están conectadas de ninguna manera, están en entornos diferentes. A pesar del mismo nombre, no se mezclan.
Cualquier bloque de código entre llaves se convierte en un entorno local. Aquí hay un ejemplo de uso de
if
:

Lo mismo sucede con
while
y
for
loops.
Entonces local significa invisible desde el exterior. Es decir, ¿global es visible en todas partes, incluso dentro de los objetos? Si!

La variable global
a
ha cambiado dentro de la función del
changer
. La función solo tiene efecto cuando se llama, no cuando se define, por lo tanto, inicialmente
a=0
, y cuando se llama,
changer
toma el valor
1
.
Es fácil sucumbir a la tentación y poner todo en un ámbito global, olvidando todas las complejidades de los entornos individuales, pero esta es una idea terrible. Las variables globales hacen que su código sea extremadamente frágil, cualquier elemento puede romper cualquier otro en cualquier momento. Por lo tanto, no use el alcance global y mantenga todo en su lugar.
Parte II Alcance léxico
Echa un vistazo a este programa:

La función
multiplier
devuelve los resultados de la multiplicación
b
.
a
da internamente, pero
b
no.
Al intentar realizar la operación de multiplicación a
a*b
, JavaScript busca los valores de
a
y
b
. Comienza a buscar dentro, y luego sale, estudiando un área tras otra, hasta que encuentra lo que estaba buscando, o no comprende que es imposible encontrarlo.
Por lo tanto, en este ejemplo, JavaScript comienza a buscar dentro del área local, dentro de la función
multiplier
. Inmediatamente encuentra el valor y pasa a
b
.
b
no lo encontrará en el entorno local, por lo que va más allá. Allí se entera de que
b
es
10
. Entonces
a*b
convierte en
5*10
, y luego en
50
.
Este fragmento de código podría estar dentro de otra función, que también está dentro de otra función. Sin encontrar
b
en la primera capa, JavaScript continuaría buscando todo en capas nuevas y nuevas, más y más.
Tenga en cuenta que
a=7
no afecta el resultado de los cálculos de ninguna manera: el valor de
a
se encontró dentro, por lo tanto, el a externo no juega
a
papel.
Esto se llama el alcance léxico. El alcance de cualquier componente está determinado por la ubicación de este componente en el código, y los bloques anidados tienen acceso a áreas externas.
Parte III Cortocircuitos
La mayoría de los lenguajes de programación admiten entornos y ámbitos, y este mecanismo permite la introducción de cierres. El cierre es inherentemente una función que "recuerda" las entidades externas utilizadas internamente.
Antes de continuar, recordemos cómo se crean y usan las funciones:

f
es una función bastante inútil que siempre devuelve
0
. El conjunto consta de dos partes: una constante y la función misma.
Es importante recordar que estos son componentes separados. El primer componente es una constante llamada
f
. Su valor puede ser un número o un valor de cadena. En este caso, el valor es una función.
En lecciones anteriores, citamos una analogía: las constantes son como hojas de papel con un nombre en un lado y un valor en el otro. Por lo tanto,
f
es una hoja de papel con
f
escrita en un lado y una descripción de la función que se inicia en el otro.
Al llamar a esta función:

Se crea un nuevo "cuadro" basado en la descripción de una hoja de papel.
De vuelta a los cierres. Aquí hay un código de muestra.

La función
createPrinter
crea una constante de
name
y luego una función llamada
printName
. Ambos son locales para la función
createPrinter
y están disponibles solo dentro de ella.
printName
sí
printName
tiene componentes locales, pero hay acceso al ámbito donde se crea, y al entorno externo, donde se asigna un
name
la constante.
La función
createPrinter
devuelve la función
printName
. Recuerde que las definiciones de funciones son descripciones de funciones en ejecución; son solo elementos de datos, como números o cadenas. Por lo tanto, podemos devolver la definición de una función de la misma manera que devolvemos números.
En el ámbito externo, creamos la constante
myPrinter
y establecemos el valor de retorno como
createPrinter
. Se devuelve una función, por lo que
myPrinter
también se convierte en una función. Cuando lo llames,
King
aparecerá en la pantalla.
Aquí está lo curioso: el
name
constante se creó dentro de la función
createPrinter
. La función fue llamada y ejecutada. Como sabes, cuando una función termina de funcionar, deja de existir. La caja mágica desaparece junto con todos los contenidos.
Pero devolvió otra función que de alguna manera recordaba el
name
constante. Por lo tanto, al llamar a
myPrinter
obtuvimos
King
, el valor que la función recuerda, a pesar de que esta área ya no existe.
La función que
createPrinter
se llama cierre. Un cierre es una combinación de una función y el entorno en el que se definió. La función "encerró" en sí misma cierta información recibida en el ámbito.
Esto puede parecer una peculiaridad extraña de JavaScript, pero el uso inteligente de los cierres puede ayudar a que su código sea más agradable, limpio y legible. El principio de devolver funciones, como devolver números y valores de cadena, le da más libertad para maniobrar.