En JavaScript, el alcance es el contexto en el que se ejecuta el código. Hay tres tipos de alcance: alcance global, alcance local (a veces denominado "alcance de función") y alcance de evaluación.
Código definido utilizando var
el interior de una función tiene un ámbito local, y solo es "visible" para otras expresiones en esa función, que incluye el código dentro de cualquier función anidada / secundaria. Se puede acceder a las variables definidas en el alcance global desde cualquier lugar porque es el nivel más alto y la última parada en la cadena de alcance.
Examine el código que sigue y asegúrese de comprender que cada declaración de foo
es único por su alcance.
Muestra: sample110.html
Asegúrate de entender que cada foo
la variable contiene un valor diferente porque cada uno está definido en un ámbito específicamente delineado.
Se puede crear un número ilimitado de funciones y ámbitos eval, mientras que un entorno JavaScript solo utiliza un ámbito global.
El alcance global es la última parada en la cadena de alcance..
Las funciones que contienen funciones crean ámbitos de ejecución apilados. Estas pilas, que están encadenadas, a menudo se conocen como la cadena de alcance.
Dado que las declaraciones lógicas (Si
) y declaraciones de bucle (para
) no crean un alcance, las variables pueden sobrescribirse unas a otras. Examine el siguiente código y asegúrese de entender que el valor de foo
Se está redefiniendo a medida que el programa ejecuta el código..
Muestra: sample111.html
Asi que foo
está cambiando a medida que se ejecuta el código porque JavaScript no tiene una función de bloqueo de alcance único, alcance global o eval.
var
Dentro de las funciones para declarar variables y evitar alcances de alcanceJavaScript declarará cualquier variable que carezca de var
declaración (incluso aquellas contenidas en una función o funciones encapsuladas) para estar en el alcance global en lugar del alcance local previsto. Eche un vistazo al código que sigue y observe que sin el uso de var
para declarar barra, la variable se define realmente en el ámbito global y no en el ámbito local, donde debería estar.
Muestra: sample112.html
El concepto para llevar aquí es que siempre debes usar var
Al definir variables dentro de una función. Esto evitará que resuelva problemas de alcance potencialmente confusos. La excepción a esta convención, por supuesto, es cuando desea crear o cambiar propiedades en el ámbito global desde una función..
Hay una cadena de búsqueda que se sigue cuando JavaScript busca el valor asociado a una variable. Esta cadena se basa en la jerarquía de alcance. En el código que sigue, estoy registrando el valor de sayHiText
desde el func2
alcance de la función.
Muestra: sample113.html
Como es el valor de sayHiText
encontrado cuando no está contenido dentro del alcance de la func2
¿función? JavaScript primero mira en el func2
función para una variable llamada sayHiText
. No encontrando func2
allí, mira hacia arriba func2
función principal, func1
. los sayHiText
variable no se encuentra en el func1
alcance, ya sea, por lo que JavaScript continúa hasta el alcance global donde sayHiText
se encuentra, en cuyo punto el valor de sayHiText
está entregado. Si sayHiText
No se había definido en el ámbito global., indefinido
habría sido devuelto por JavaScript.
Este es un concepto muy importante para entender. Examinemos otro ejemplo de código, uno en el que tomamos tres valores de tres ámbitos diferentes.
Muestra: sample114.html
El valor para z
es local al bar
función y el contexto en el que el console.log
se invoca El valor para y
está en el foo
función, que es el padre de bar()
, y el valor para X
Está en el ámbito global. Todos estos son accesibles a la bar
Funcionar a través de la cadena de alcance. Asegúrese de que entiende que las variables de referencia en el bar
La función revisará todo el camino hasta la cadena de alcance para las variables a las que se hace referencia.
La cadena de alcance, si lo piensas, no es tan diferente de la cadena del prototipo. Ambos son simplemente una forma de buscar un valor al verificar un conjunto sistemático y jerárquico de ubicaciones.
En el ejemplo de código que sigue, una variable llamada X
Existe en el mismo ámbito en el que se examina con console.log
. Este valor "local" de X
se utiliza, y se podría decir que sombrea, o máscaras, el nombre idéntico X
Las variables se encuentran más arriba en la cadena de alcance..
Muestra: sample115.html
Recuerde que la búsqueda de alcance finaliza cuando la variable se encuentra en el enlace disponible más cercano de la cadena, incluso si el mismo nombre de variable se usa más arriba en la cadena.
Como las funciones determinan que el alcance y las funciones se pueden pasar como cualquier valor de JavaScript, se podría pensar que descifrar la cadena de alcance es complicado. En realidad es muy simple. La cadena de alcance se decide en función de la ubicación de una función durante la definición, no durante la invocación. Esto también se llama alcance léxico. Piense mucho en esto, ya que la mayoría de las personas se tropieza con él con frecuencia en el código JavaScript..
La cadena de alcance se crea antes de invocar una función. Debido a esto, podemos crear cierres. Por ejemplo, podemos hacer que una función devuelva una función anidada al ámbito global, pero nuestra función aún puede acceder, a través de la cadena de alcance, al alcance de su función principal. En la siguiente muestra, definimos una función de los padres
que devuelve una función anónima, y llamamos a la función devuelta desde el ámbito global. Porque nuestra función anónima fue definida como contenida dentro de función de los padres
, todavía tiene acceso a funciones de los padres
alcance cuando se invoca. Esto se llama un cierre.
Muestra: sample116.html
La idea que debe quitar aquí es que la cadena de alcance se determina durante la definición, literalmente, en la forma en que se escribe el código. Pasar las funciones dentro de su código no cambiará la cadena de alcance.
Tome lo que ha aprendido sobre la búsqueda de alcance y cadena de alcance de este artículo, y un cierre no debería ser demasiado complicado de entender. En el siguiente ejemplo, creamos una función llamada CountUpFromZero
. Esta función en realidad devuelve una referencia a la función secundaria contenida en ella. Cuando se invoca esta función secundaria (función anidada), todavía tiene acceso al alcance de la función principal debido a la cadena de alcance.
Muestra: sample117.html
Cada vez que el CountUpFromZero
se invoca la función, la función anónima contenida en (y devuelta desde) la CountUpFromZero
La función todavía tiene acceso al ámbito de la función principal. Esta técnica, facilitada a través de la cadena de alcance, es un ejemplo de cierre..
Si sientes que tengo cierres demasiado simplificados, es probable que tengas razón en este pensamiento. Pero lo hice a propósito, ya que creo que las partes importantes provienen de una sólida comprensión de las funciones y el alcance, no necesariamente las complejidades del contexto de ejecución. Si necesita una inmersión profunda en los cierres, eche un vistazo a los cierres de JavaScript.