[Pregunta de la entrevista] ¿Cuál es el concepto básico que JS es difícil de entender en su comprensión?

Recomendación  del banco de preguntas de la entrevista inicial ( necesario para la entrevista) : ★★★★★            

Dirección: banco de preguntas de la entrevista inicial

Alcance y cierres

alcance

Un alcance es el contexto de ejecución actual en el que los valores y expresiones son "visibles" o accesibles. Si una variable o expresión no está en el alcance actual, entonces no está disponible. Los ámbitos también se pueden apilar en jerarquías, donde los ámbitos secundarios tienen acceso a los ámbitos principales, pero no al revés. ———MDN

La característica más importante de los ámbitos es que los ámbitos secundarios pueden acceder a los ámbitos principales, pero no al revés .

El alcance se puede subdividir en 4 tipos:

  • Ámbito global: el ámbito de la fraternidad, al que se puede acceder desde cualquier lugar.
  • Alcance del módulo: un alcance independiente de un archivo.
  • Alcance de la función: Cada función tiene su alcance.
  • Alcance a nivel de bloque: este es el alcance que apareció después de que ES6 introdujo let y const.

A continuación, he "robado" You-Dont-Know-JSel ejemplo del libro que presenta el alcance y los cierres.

figura2.png

 1, 2 y 3 son alcance global, alcance de función y alcance a nivel de bloque, respectivamente. También puede ver claramente la estructura jerárquica del alcance. Creo que todos deben haber visto estas preguntas de la entrevista:

for(var i = 1;i<5;i++ ){
	setTimeout(()=>{
    console.log(i)
  },1000)
}
// 5 5 5 5 5

¿Qué es este extraño fenómeno? Echemos un vistazo al cierre, hablemos de ello.

Cierre

Un cierre es una combinación de una función y una referencia a su estado ambiental circundante incluido ( entorno léxico , entorno léxico ). En otras palabras, los cierres permiten a los desarrolladores acceder al alcance de las funciones externas desde las funciones internas. En JavaScript, los cierres se crean al mismo tiempo que se crean las funciones. ———MDN

Vaya, a primera vista esta definición te confundirá. Pero tras una inspección más cercana, en realidad estaba bastante confundido. Cambiemos un poco el ángulo y será más fácil de entender.

Cuando se crea una función en JS, forma un cierre. Simulative understanding, you raised a puppy, and the puppy followed you when it was born, and its life and mind are all about you (wooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo The dog cannot be transferred), even if it is kidnapped, changed owners, and abandoned by you, siempre estás en su mente... Hablando de esto, casi estoy llorando, qué conmovedor. Los cierres son así: cuando se crea una función, recordará en qué ámbito se creó.

Dé un ejemplo de código:

function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

En este caso, una referencia a la instancia de función  creada en el  momento myFunc de la ejecución   .  Una instancia de mantiene una referencia a su entorno léxico (   en el que existe la variable). Por lo tanto, cuando   se llama, la variable   todavía está disponible y su valor   se pasa a . ———Lo anterior es la explicación de MDN.makeFuncdisplayNamedisplayNamenamemyFuncnameMozillaalert

Ahora parece que es fácil de entender, displayName es este cachorro, incluso si myFunc lo adopta, todavía recuerda todo sobre makeFunc ...

Así que regrese y mire esta pregunta de la entrevista:

for(var i = 1;i<5;i++ ){
	setTimeout(()=>{
    console.log(i)
  },1000)
}
// 5 5 5 5 5 

Oye, todavía es extraño por qué isolo recuerdo el resultado final y el proceso intermedio ya no está. Piensa en una pregunta, i¿en qué ámbito? i está fuera del alcance de un bucle for, i es solo uno y se agrega constantemente. Cuando comienzan a ejecutarse múltiples funciones setTimeout, todas usan una i.

Entonces, ¿cómo solucionarlo?

Utilice let para crear ámbitos a nivel de bloque únicos para cada bucle y recordarán cuál es el suyo i.

for(let i = 1;i<5;i++ ){
	setTimeout(()=>{
    console.log(i)
  },1000)
}
// 1 2 3 4 5

Bucle de eventos: microtareas y macrotareas

Tanto JavaScript en el navegador como los procesos en NodeJs se basan en el bucle de eventos.

El bucle de eventos es un proceso en el que el motor JavaScript realiza un bucle constante en los dos estados de espera de tareas y ejecución de tareas.

Las tareas se dividen en dos categorías: macrotareas y microtareas (ambas son tareas asincrónicas).

tarea macro

  • Representación de eventos (renderización DOM, redibujado, diseño informático)
  • Eventos de interacción del usuario (ratón, teclado, etc.)
  • solicitud de red
  • Eventos de secuencias de comandos JavaScript

Para controlar mejor las tareas, el proceso de la página introduce una cola de mensajes y un mecanismo de bucle de eventos, y agrega las tareas macro que se ejecutarán a la cola una por una, respetando el buen carácter de primero en entrar, primero en salir, y las ejecuta. en orden de manera ordenada ... Date una palmada en el trasero y sal de la cola.

Pero para controlar el tiempo preciso , las tareas macro son difíciles de realizar.

El sistema agrega a la cola eventos DOM, eventos de interacción del usuario, solicitudes de red y otras tareas. No conocemos su orden en la cola, por lo que no tenemos forma de saber cuándo comienzan las tareas.

Por ejemplo:

<!DOCTYPE html>
<html>
  <body>
    <div id="content">
      <li>xx</li>
    </div>
  </body>
  <script type="text/javascript">
    function timer2() {
      console.log("我来咯~");
    }
    function timer() {
      console.log('我开始咯,你来追我呀');
      setTimeout(timer2, 0);
    }
    setTimeout(timer, 0);
  </script>
</html>

En el ejemplo, la tarea del script JavaScript tiene dos temporizadores, son una pareja muy dulce. Lo único que queremos es que se mantengan unidos, dulcemente. Es decir, el tiempo de ejecución de los dos temporizadores está perfectamente conectado, pero aunque el intervalo de ejecución de setTimeout se puede establecer en 0, en realidad tiene un intervalo de 4 ms, por lo que es muy probable que el sistema agregue algunas tareas durante este intervalo Colas, colas interrumpidas.

La gran granularidad temporal de las macrotareas dificulta el cumplimiento de algunos requisitos elevados en tiempo real.

En este momento surgieron las microtareas.

microtarea

El tiempo de ejecución de la microtarea es después de que finaliza la ejecución de la función principal y antes de que finalice la ejecución de la macro función actual. Entonces, lo primero que me viene a la mente es el controlador de promesa .then/.catch.

Sí, son microtareas típicas.

Las macrotareas tienen sus colas de mensajes y las microtareas también tienen sus colas de mensajes. Cuando el JavaScript en la macrotarea está a punto de terminar de ejecutarse, el motor de JavaScript verificará si hay tareas en la cola de microtareas actual y, de ser así, las ejecutará en orden.

 

Recomendación del banco de preguntas de la entrevista inicial ( necesario para la entrevista) : ★★★★★            

Dirección: banco de preguntas de la entrevista inicial

Supongo que te gusta

Origin blog.csdn.net/weixin_42981560/article/details/132458216
Recomendado
Clasificación