Cómo comenzar rápidamente con VUE3.0: Ingrese al aprendizaje
Recomendaciones relacionadas: Tutoriales de JavaScript
Probablemente escuchemos a menudo "entorno de ejecución", "alcance", "prototipo (cadena)", "contexto de ejecución", etc.
Sabemos que js es un lenguaje débilmente tipado y el tipo de variable se determina solo en tiempo de ejecución. Cuando el motor js ejecuta el código js, también realizará análisis léxico , análisis de sintaxis , análisis semántico y otros procesamientos de arriba a abajo, y generará un AST (árbol de sintaxis abstracta) después de que se complete el análisis del código y finalmente generará código de máquina. que la CPU puede ejecutar en función del AST y ejecutar.
Además, el motor JS también realizará otros procesamientos al ejecutar el código. Por ejemplo, hay dos etapas en V8:
Esto conduce a dos conceptos: "contexto de ejecución" y "cadena de alcance".
De lo anterior podemos saber: cuando el código js ejecuta un fragmento de código ejecutable, se creará el contexto de ejecución correspondiente.
En primer lugar, existe un concepto correspondiente al código ejecutable en js: "entorno de ejecución": entorno global, entorno de función y eval
.
En segundo lugar, para cada contexto de ejecución, hay tres atributos importantes:
Veamos dos fragmentos de código:
var alcance="alcance global" función checkscope(); var alcance="alcance local"; función f(){ alcance de devolución; } return f();}checkscope();
var alcance="alcance global";función checkscope(){ var alcance="alcance local"; función f(){ alcance de devolución; } return f;}checkscope()();
¿Qué imprimirán?
¿Por qué? ¡La respuesta es que sus pilas de contexto de ejecución son diferentes!
¿Qué es la "pila de contexto de ejecución"?
Al ejecutar un código ejecutable, los preparativos se realizarán con anticipación. Los "preparativos" aquí se denominan profesionalmente "contexto de ejecución". Pero con el aumento de códigos ejecutables como funciones, ¿cómo gestionar tantos contextos de ejecución? Entonces el motor JS creó el concepto de pila de contexto de ejecución.
Podemos usar completamente una matriz para simular su comportamiento (siempre hay un contexto de ejecución global globalContext en la parte inferior de la pila).
Definimos un EStack, primero
EStack=[globalContext]
y luego simulamos el primer fragmento de código:
EStack. push(<checkscope> functionContext); EStack.push(<f> functionContext);EStack.pop();EStack.pop();
Y el segundo fragmento de código es así:
EStack.push(<checkscope> functionContext); EStack.pop();EStack.push (<f> functionContext);EStack.pop(); ¡
La razón es que es posible que primero necesites estudiar el concepto de "cierre"!
Por cierto, ¿cómo lograr un "ahorro de datos a largo plazo" en la "modulación frontal"?
¿cache? No. ¡Cierre!
En primer lugar, el alcance se refiere al área del programa donde se definen las variables. El alcance especifica cómo encontrar la variable, lo que determina los derechos de acceso del código que se está ejecutando actualmente a la variable.
Hay dos tipos de alcance: alcance estático y alcance dinámico .
El alcance estático utilizado por JS también se denomina "alcance léxico". El alcance de una función se determina cuando se define la función.
De lo anterior, las variables en el alcance léxico tendrán un cierto alcance durante el proceso de compilación. Este alcance es el "contexto de ejecución actual". Después de ES5 usamos "entorno léxico" en lugar de alcance para describir el contexto de ejecución. El entorno léxico consta de dos miembros:
Veamos todavía un ejemplo:
valor var=1 ;función foo(){ console.log(valor);}barra de funciones(){ valor var=2; foo();}bar();
Volviendo a la definición anterior, ¿qué se debe imprimir?
Analicemos el proceso de ejecución:
Ejecute la función foo(), primero busque dentro de la función foo para ver si hay un valor de variable local. De lo contrario, busque el código en la capa superior según la posición cuando se definió, es decir, valor = 1. Entonces el resultado se imprimirá como 1.
Por supuesto, esto no es tan simple y se puede resumir. Puede analizarlo desde la perspectiva del contexto de ejecución.
Anteriormente hablamos de los dos componentes del entorno léxico (alcance). Combinado con el contexto de ejecución, no es difícil encontrar que a través de la referencia del entorno léxico externo, el alcance se puede expandir a lo largo de la pila capa por capa, estableciendo una estructura de cadena que se extiende hacia afuera desde el entorno actual.
Veamos otro ejemplo:
función foo(){ consola.dir(barra); var a = 1; barra de funciones(){ a=2; }}console.dir(foo);foo();
Desde el alcance estático, la función global foo crea un atributo [[scope]]
de su propio objeto
foo
[[scope]]=[globalContext];
(), también ingresará sucesivamente el período de definición y el período de ejecución de la función foo. Durante el período de definición de la función foo, el [[scope]]
de la barra de funciones incluirá el alcance integrado global y el alcance integrado de foo
bar[[scope]]=[fooContext,globalContext]
Esto prueba
;este punto: "JS pasará Las referencias del entorno léxico externo se utilizan para crear una cadena de alcance de objetos variables, asegurando así el acceso ordenado a las variables y funciones a las que tiene acceso el entorno de ejecución".
Volvamos a la pregunta en el contexto de ejecución, dijimos antes. ¿Cuál es la diferencia entre ellos? Hablemos de por qué imprimen "alcance local" de la misma manera: sigue siendo la misma oración "JS usa alcance léxico y el alcance de la función depende de la ubicación donde se crea la función". ” - Ejecución de la función JS Se utiliza una cadena de alcance, que se crea cuando se define la función. La función anidada f () se define en esta cadena de alcance, y el alcance de la variable en ella debe hacer referencia a variables locales No importa cuándo y dónde se ejecuta f (), este enlace sigue siendo válido cuando se ejecuta f ().
Cuando no se puede encontrar una variable en su propio registro de entorno léxico, se puede buscar en la capa externa según la referencia del entorno léxico externo hasta que la referencia del entorno léxico externo en el entorno léxico más externo sea null
.
Similar a esto es la "búsqueda basada en cadena de prototipos en objetos":
__proto__
es nulo)La diferencia también es obvia: la cadena de prototipo es un enlace que establece la herencia de objetos a través del atributo de prototipo, mientras que la cadena de alcance se refiere al cierre que permite que las funciones internas accedan a funciones externas. Ya sea directa o indirectamente, todas las cadenas de alcance de funciones se vinculan en última instancia con el contexto global.
Recomendaciones relacionadas: Tutorial de aprendizaje de JavaScript
Lo anterior es una comprensión profunda de cómo el motor JavaScript ejecuta el código JS. Para obtener más información, preste atención a otros artículos relacionados en el sitio web chino de PHP.