En esta conferencia, respondamos la pregunta.
¿Cómo se ejecuta el código JavaScript?
Ya sabemos que sucede en una pila de llamadas.
en el motor, pero profundicemos un poco más ahora.
y comencemos
suponiendo que nuestro código acababa de terminar de compilarse.
Justo en la forma en que aprendimos en la última lección.
Entonces el código ahora está listo para ser ejecutado.
Qué pasa entonces,
es que se crea un llamado contexto de ejecución global
para el código de nivel superior.
Y el código de nivel superior es básicamente código que no es
dentro de cualquier función.
Así que de nuevo, al principio
solo se ejecutará el código que esté fuera de funciones.
Y esto tiene sentido, ¿verdad?
Las funciones solo deben ejecutarse cuando se las llama.
Y en realidad ya vimos que esto sucedía
en nuestro proyecto de juego de cerdos.
Así que ahí teníamos una función de inicio,
que inicializó todo nuestro proyecto
pero para poder inicializar el juego
la primera vez que cargó la página,
necesitábamos llamar a esa función inmediatamente
en nuestro código de nivel superior.
Y eso es lo que quiero decir aquí.
Pero de todos modos, también podemos ver
qué código de nivel superior es en este ejemplo aquí.
Así que esta declaración de variable de nombre
es claramente el código de nivel superior, ¿verdad?
Y por lo tanto se ejecutará
en el contexto de ejecución global.
A continuación, tenemos dos funciones, una expresión,
y una declaración.
Así estos también serán declarados,
para que puedan ser llamados más tarde.
Pero el código dentro de las funciones,
solo se ejecutará cuando se llame a las funciones.
Bien, sabemos que un contexto de ejecución global
se crea para el código de nivel superior.
Pero ahora, ¿qué es exactamente un contexto de ejecución?
Bueno, un contexto de ejecución es un concepto abstracto.
Pero lo defino básicamente como un entorno
en el que se ejecuta una pieza de JavaScript.
Es como una caja que almacena toda la información necesaria.
para que se ejecute algún código.
Como variables locales o argumentos pasados ​​a una función.
Entonces, el código JavaScript siempre se ejecuta dentro de un contexto de ejecución.
Y para hacer esto un poco más intuitivo
imaginemos que pides una pizza en una comida para llevar.
Entonces, por lo general, esa pizza viene en una caja, ¿verdad?
Y también puede venir
con algunas otras cosas que son necesarias
para que te comas una pizza como cubiertos o un recibo,
para que puedas pagar la pizza antes de comerla.
Entonces, en esta analogía,
la pizza es el código JavaScript a ejecutar,
y el cuadro es, por supuesto, el contexto de ejecución
para nuestra pizza.
Y eso es porque comer la pizza sucede dentro de la caja.
que es entonces el ambiente para comer pizza.
La caja también contiene cubiertos y el recibo,
que son necesarios para comer una pizza
o en otras palabras, para ejecutar el código, ¿de acuerdo?
Espero que tenga sentido,
y para hacer el concepto de contexto de ejecución
un poco más claro.
Ahora, en cualquier proyecto de JavaScript, sin importar cuán grande sea,
solo hay un contexto de ejecución global.
Siempre está ahí como el contexto predeterminado,
y es donde se ejecutará el código de nivel superior.
Y hablando de ejecutar,
ahora que tenemos un ambiente
donde se puede ejecutar el código de nivel superior,
finalmente se ejecuta.
Y no hay mucho que decir sobre la ejecución en sí.
Es solo el procesamiento de la CPU de la computadora
el código de máquina que recibió.
Vale, y una vez este el primer código,
por lo que el nivel superior del código está terminado,
las funciones finalmente comienzan a ejecutarse también.
Y así es como funciona.
Para todas y cada una de las llamadas a funciones,
y se creará su contexto de ejecución
que contiene toda la información necesaria
para ejecutar exactamente esa función.
Y lo mismo ocurre con los métodos, por supuesto,
porque son simplemente funciones
adjunto a los objetos ¿recuerdas?
De todos modos, todos estos contextos de ejecución juntos,
componen la pila de llamadas que mencioné antes.
Pero más sobre eso en un segundo.
Ahora, cuando todas las funciones hayan terminado de ejecutarse,
el motor básicamente seguirá esperando
para que lleguen las funciones de devolución de llamada
para que pueda ejecutarlos.
Por ejemplo, una función de devolución de llamada asociada
con un evento de clic.
Y recuerda, que es el bucle de eventos quien proporciona
estas nuevas funciones de devolución de llamada
como aprendimos en la última lección.
Está bien.
Ahora sabemos qué es un contexto de ejecución,
pero no sé muy bien de qué está hecho.
Entonces, ¿qué hay dentro de él?
Y entonces, averigüemos eso a continuación.
Y lo primero que está dentro de cualquier contexto de ejecución
es un llamado entorno variable.
En este entorno,
todas nuestras variables y declaraciones de funciones se almacenan,
y también hay un objeto de argumentos especiales.
Este objeto contiene,
como su nombre lo dice todos los argumentos que se pasaron
en la función que el contexto de ejecución actual
pertenece a.
Porque recuerda cada función
obtiene su propio contexto de ejecución
tan pronto como se llame a la función.
Así que básicamente todas las variables
que de alguna manera se declaran dentro de una función,
terminará en su entorno variable.
Sin embargo, una función también puede acceder a variables.
fuera de la función.
Y eso ya lo hemos visto en acción.
a lo largo de este curso,
especialmente en los proyectos del apartado anterior.
Y esto funciona debido a algo llamado cadena de alcance.
Y aprenderemos todo sobre el alcance
y la cadena de alcance más adelante en la sección.
Pero por ahora, lo que necesitas saber
es que la cadena de alcance consiste básicamente en
referencias a variables que se encuentran
fuera de la función actual.
Y para realizar un seguimiento de la cadena de alcance,
se almacena en cada contexto de ejecución.
Finalmente, cada contexto también obtiene una variable especial
llamó a esta palabra clave.
Y una vez más, hay una conferencia especial.
casi la palabra clave this más adelante en la sección.
Bueno.
Ahora, el contenido del contexto de ejecución,
entorno tan variable, cadena de alcance
y esta palabra clave se genera en una llamada fase de creación.
Lo que sucede justo antes de la ejecución.
Y ahora solo una final
pero un detalle muy importante que debemos tener en cuenta,
es que los contextos de ejecución pertenecientes a funciones de flecha,
no obtenga sus propios argumentos palabra clave,
ni obtienen la palabra clave this, ¿de acuerdo?
Entonces, básicamente funciones de flecha
no tiene el objeto argumentos
y la palabra clave this.
En su lugar, pueden usar el objeto arguments,
y esta palabra clave
de su padre de función regular más cercano.
Y este es un detalle extremadamente importante para recordar.
sobre las funciones de flecha y volveremos a ello más adelante.
Entonces estas son las cosas
que son necesarios para ejecutar cada función
así como el código en el nivel superior.
Ahora, detrás de escena, en realidad es aún más complejo.
pero creo que estamos bien así, ¿no?
Y ahora intentemos simular la fase de creación.
para este ejemplo de código aquí.
Entonces, como es de esperar que sepa, a estas alturas,
obtendremos un contexto de ejecución global
y uno para cada función.
Así que uno para la primera función,
y uno para la segunda función.
En el contexto mundial,
tenemos la declaración de variable de nombre,
las declaraciones de la primera y segunda función,
así como la declaración de la variable X.
Para las funciones, la variable entorno.
literalmente contendrá todo el código
de una función particular.
Ahora el valor de X está marcado como desconocido aquí,
porque este valor es el resultado
de la primera función que aún no ejecutamos.
Pero simularemos esto en la siguiente diapositiva.
Ahora, técnicamente, ninguno de estos valores se conoce realmente.
durante la fase de creación, pero sólo en la fase de ejecución.
Así que esto no es 100% exacto aquí,
pero es solo para ilustrar
cómo funcionan estos contextos de ejecución.
¿Bueno? Así que tenlo en cuenta.
De todos modos, ahora en la primera función,
tenemos la variable a establecida en 1 y la variable b
que una vez más requiere una llamada de función
para darse a conocer.
Finalmente, la variable entorno de la segunda función,
contiene la variable C establecida en 2,
y como esta es una función irregular,
así que no es una función de flecha, también tiene el objeto de argumentos.
Y este objeto es una matriz,
que contiene todos los argumentos que se pasaron
en la función cuando fue llamada.
En este caso, como puede ver, son 7 y 9.
Bastante simple, ¿verdad?
Bueno, es simple porque este es un extremadamente pequeño
cantidad de código.
Pero ahora imagina que hay cientos de contextos de ejecución
para cientos de funciones.
¿Cómo hará el seguimiento el motor?
del orden en que funciones nos llaman?
¿Y cómo sabrá dónde se encuentra actualmente?
en la ejecución?
Bueno, ahí es donde finalmente entra la pila de llamadas.
Y recuerda que la pila de llamadas,
junto con el montón de memoria,
constituye el propio motor de JavaScript.
Pero, ¿qué es realmente la pila de llamadas?
Bueno, básicamente es un lugar donde los contextos de ejecución
apilarse uno encima del otro,
para hacer un seguimiento
de dónde estamos en la ejecución de los programas.
Entonces, el contexto de ejecución que está en la parte superior de la pila,
es el que se está ejecutando actualmente.
Y cuando termine de ejecutarse,
será eliminado de la pila,
y la ejecución volverá
al contexto de ejecución anterior.
Y usando la analogía de antes,
es como si compraras pizzas con unos amigos.
Cada amigo tiene una caja de pizza, y luego pones las cajas
uno encima del otro, formando una pila,
con el fin de realizar un seguimiento, qué pizza pertenece a cada amigo.
Ahora, todo esto suena un poco abstracto, ¿no?
Y para demostrar cómo funciona la pila de llamadas,
analicemos juntos este ejemplo de código,
para que pueda mostrarte exactamente lo que sucede.
Entonces, una vez compilado el código,
el código de nivel superior comenzará a ejecutarse.
Y luego, como aprendimos al comienzo de la conferencia,
se creará un contexto de ejecución global
para el nivel superior de código, ¿verdad?
Así que aquí es donde todo el código fuera de cualquier función
será ejecutado.
¿Y qué sucede con este contexto de ejecución?
Así es, se pondrá en la pila de llamadas.
Y dado que este contexto ahora está en la parte superior de la pila,
es aquel donde el código se está ejecutando actualmente.
Entonces, continuemos ahora con esta ejecución.
Así que aquí hay una declaración de variable simple.
Y luego se declaran la primera y la segunda funciones.
Así que nada especial, pero así es como el código de nivel superior normal
se ejecuta
Pero luego, en la última línea
es donde las cosas empiezan a ponerse interesantes.
Aquí, declaramos la variable X,
con el valor que se va a devolver
de llamar a la primera función.
Y entonces llamemos a esa función.
Ahora, ¿qué sucede inmediatamente cuando se llama a una función?
Bueno, obtiene su propio contexto de ejecución.
para que pueda ejecutar el código que está dentro de su cuerpo.
Perfecto.
¿Y qué pasa con el contexto?
Bueno, nuevamente se coloca en la pila de llamadas,
además del contexto actual,
y ahora es el nuevo contexto de ejecución actual.
Excelente.
Entonces, continuemos.
Entonces tenemos otra declaración de variable simple aquí,
y esta variable, por supuesto, se definirá
en el entorno variable
del contexto de ejecución actual,
y no en el contexto global, ¿verdad?
Luego, justo en la siguiente línea, tenemos otra llamada de función.
Entonces, llamemos a esa función y muévase allí.
Y como adivinaste, un nuevo contexto de ejecución.
fue creado de inmediato para esta segunda función.
Y una vez más, se empuja
en la pila de llamadas y se convierte en el nuevo acto de contexto.
Ahora lo que es importante notar aquí es que la ejecución
de la primera función ahora se ha pausado, ¿de acuerdo?
De nuevo, estamos ejecutando la segunda función ahora.
y mientras tanto, no se ejecuta ninguna otra función.
La primera función se detuvo en este punto.
donde se llamó a la segunda función
y sólo continuará tan pronto
como esta segunda función regresa.
Y tiene que funcionar de esta manera porque recuerda,
JavaScript tiene solo un hilo de ejecución.
Por lo tanto, solo puede hacer una cosa a la vez.
¿Bueno? Nunca olvides eso.
Ahora, pasando a la siguiente línea, tenemos una declaración de devolución
lo que significa que la función terminará su ejecución.
Entonces, ¿qué significa eso para la pila de llamadas?
Bueno, básicamente significa
que el contexto de ejecución de la función,
se sacará de la pila
y desaparecer de la memoria de la computadora.
Al menos eso es lo que necesitas saber por ahora.
porque en realidad el contexto de ejecución apareció
podría seguir viviendo en la memoria.
Pero más sobre eso más adelante en el curso.
De todos modos, lo que sucede a continuación,
es que el contexto de ejecución anterior, ahora volverá
a ser el contexto de ejecución activo de nuevo.
Y entonces volvamos también a donde estábamos
antes en el código.
Y espero que por ahora,
empiezas a ver cómo la pila de llamadas realmente realiza un seguimiento
de la orden de ejecución aquí.
Sin la pila de llamadas,
¿Cómo sabría el motor qué función
estaba siendo ejecutado antes?
No sabría a dónde volver, ¿verdad?
Y esa es la belleza de la pila de llamadas.
Hace que este proceso sea casi sin esfuerzo.
Así que me gusta usar la analogía
de la pila de llamadas como un mapa
para el motor JavaScript.
Porque la pila de llamadas asegura
que la orden de ejecución nunca se pierda.
Al igual que un mapa, al menos si lo usas correctamente.
Está bien.
Entonces, volvimos de la segunda función,
o volver a la primera función
donde tenemos este cálculo,
y finalmente esta primera función también regresa.
Y así aquí sucede lo mismo que antes.
Entonces, el contexto de ejecución actual se saca de la pila,
y el contexto anterior es ahora el contexto actual
donde se ejecuta el código.
En este caso, volvemos al contexto de ejecución global.
y la línea de código donde se encuentra la primera función
fue llamado por primera vez.
Así que aquí, el valor devuelto finalmente se asigna a X
y la ejecución ha terminado.
Ahora el programa permanecerá en este estado
para siempre hasta que finalmente esté realmente terminado.
Y eso solo sucede cuando cerramos la pestaña del navegador,
o la ventana del navegador.
Sólo cuando el programa está realmente terminado así,
es cuando el contexto de ejecución global
también se saca de la pila.
Y así es en pocas palabras cómo funciona la pila de llamadas.
Así que espero que tenga sentido ahora que decimos
ese código Java script se ejecuta dentro de la pila de llamadas.
Y en realidad es más exacto decir
ese código se ejecuta dentro de los contextos de ejecución
que están en la pila.
Pero el punto general es que el código se ejecuta en la pila de llamadas,
lo cual es por supuesto cierto.
Excelente.
A continuación, aprenderemos un poco más
sobre el entorno variable,
y cómo se crean las variables.
Así que estad atentos al próximo vídeo.