Las palabras anteriores
La mayoría de las veces, la razón principal por la que estamos confundidos sobre el alcance es que no podemos distinguir si las búsquedas variables deben realizarse en las posiciones de orden anidadas de la función o en el orden de las llamadas de funciones. Junto con la interferencia de este mecanismo, la búsqueda variable es muy propensa a los errores. Esto en realidad es causado por dos modelos de trabajo de alcance. El alcance se divide en alcance léxico y alcance dinámico. Al distinguir estos dos modelos de alcance, puede tener una comprensión clara del proceso de búsqueda de variables. Este artículo es el segundo capítulo de la serie de alcance de JavaScript: alcance léxico y alcance dinámico
Alcance léxico
Como se menciona en el primer artículo, la primera etapa de trabajo del compilador se llama Word Participle, que descompone una cadena compuesta de caracteres en unidades léxicas. Este concepto es la base para comprender el alcance léxico
En pocas palabras, el alcance léxico define el alcance en la etapa léxica, que se determina por dónde se escriben las variables y el alcance del bloque al escribir el código. Por lo tanto, el alcance permanece sin cambios cuando el analizador léxico procesa el código.
relación
No importa a dónde se llame la función, y no importa cómo se llame, su alcance léxico está determinado solo por la posición donde se declara la función.
función foo (a) {var b = a * 2; barra de funciones (c) {console.log (a, b, c);} bar (b * 3);} foo (2); // 2 4 12En este ejemplo, hay tres ámbitos anidados. Para ayudar a comprender, piense en ellas como varias burbujas que se incluyen paso a paso
Las burbujas de alcance se determinan por dónde se escribe su código de bloque de alcance correspondiente, y se incluyen paso a paso.
Bubble 1 contiene todo el alcance global, con solo un identificador: Foo
Bubble 2 contiene el alcance creado por Foo, que tiene tres identificadores: A, Bar y B
Bubble 3 contiene el alcance creado por Bar, con solo un identificador: C
Encontrar
La estructura de las burbujas de alcance y sus relaciones posicionales proporcionan al motor información de posición suficiente, que el motor utiliza para encontrar la ubicación del identificador.
En el fragmento de código, el motor ejecuta la declaración de console.log (...) y busca referencias a las tres variables A, B y C. Primero comienza con el alcance más interno, es decir, el alcance de la función de la barra (...). El motor no puede encontrar un aquí, por lo que irá al nivel anterior para continuar buscando en el alcance del foo anidado (...). A se encuentra aquí, por lo que el motor usa esta referencia. Lo mismo ocurre con b. Y para C, el motor lo encontró en la barra (...)
[Nota] La búsqueda de alcance léxico solo buscará identificadores de primer nivel. Si el código hace referencia a foo.bar.baz, la búsqueda de alcance léxico solo intentará encontrar identificadores FOO. Después de encontrar esta variable, las reglas de acceso a atributos del objeto se hacen cargo del acceso a la barra y los atributos de BAZ respectivamente
foo = {bar: {Baz: 1}}; console.log (foo.bar.baz); // 1Cubrir
La búsqueda en el alcance comienza desde el alcance más interno en el que se encuentra el tiempo de ejecución, y procede paso a paso hacia afuera o hacia arriba hasta que se cumple el primer identificador coincidente.
Los identificadores con el mismo nombre se pueden definir en ámbitos anidados de múltiples capas, que se llama "efecto de oclusión". Los identificadores internos "ocluyen" identificadores externos
var a = 0; function test () {var a = 1; console.log (a); // 1} test ();Las variables globales son atributos automáticamente de objetos globales, por lo que se puede acceder directamente a ellas por referencia a los atributos de los objetos globales en lugar de pasar directamente a través del nombre léxico del objeto global.
var a = 0; función test () {var a = 1; console.log (window.a); // 0} test ();Esta técnica permite el acceso a variables globales oscurecidas por variables del mismo nombre. Pero si las variables no globales están bloqueadas, no se puede acceder a ellas sin importar qué.
Alcance dinámico
JavaScript utiliza el alcance léxico, y su característica más importante es que su proceso de definición tiene lugar durante la etapa de escritura del código.
Entonces, ¿por qué introducir el alcance dinámico? De hecho, el alcance dinámico es otro mecanismo importante de JavaScript para enfrentar esto. La mayor parte de la confusión del alcance se debe a que el alcance léxico y este mecanismo están confundidos, por lo que no puedo notar la diferencia entre estúpidamente
Los ámbitos dinámicos no les importa cómo las funciones y los ámbitos se declaran y declaran en cualquier lugar, solo donde se les llama. En otras palabras, las cadenas de alcance se basan en la pila de llamadas, no de anidación de alcance en el código
var a = 2; function foo () {console.log (a);} function bar () {var a = 3; foo ();} bar ();[1] Si está en el alcance léxico, es el entorno de JavaScript actual. La variable A se busca primero en la función foo (), pero no se encuentra. Así que siga la cadena de alcance para buscar en el alcance global, encuentre y asigne un valor de 2. Entonces la consola sale 2
【2】 Si está en alcance dinámico, de manera similar, la variable A se busca primero en foo () y no se encuentra. Aquí, seguirá la pila de llamadas para buscar en el lugar donde se llama la función foo (), es decir, la función bar (), encontrar y asignar el valor a 3. Por lo tanto, la consola sale 3
Resumen: la diferencia entre los dos ámbitos. En resumen, el alcance léxico se determina en el momento de la definición, mientras que el alcance dinámico se determina en tiempo de ejecución.
Lo anterior es la segunda parte del alcance léxico y el alcance dinámico introducido por el editor para usted. Espero que te sea útil. Si desea saber más, ¡preste atención a Wulin.com!