confundido acerca de la declaración de función en {}

18

var a;
if (true) {
  a = 5;

  function a() {}
  a = 0;
  console.log(a)
}
console.log(a)

Vi el código anterior, una función se declara en {}. Creo que imprimiría 0 0, pero imprime 0 5

Marcus Lee
fuente
1
En modo estricto, se registra 0 undefined.
CertainPerformance
@certainPerformance bien, eso es explicable, pero no puedo explicar que a = 5deja el bloque. Según bergi en el dupe, function aserá izado.
Jonas Wilms
2
Parece que la variable de bloque de ámbito local se copia en el bloque externo cuando se alcanza la declaración de función.
Jonas Wilms

Respuestas:

13

Sucede lo siguiente:

(1) Existen dos declaraciones de variables a, una dentro del bloque y otra fuera del mismo.

(2) La declaración de función se iza y se une a la variable de bloques internos.

(3) a = 5se alcanza, lo que anula la variable de bloque.

(4) se alcanza la declaración de función y la variable de bloque se copia en la variable externa. Ambos son 5 ahora.

(5) a = 0se alcanza, lo que anula la variable de bloque. La variable externa no se ve afectada por esto.

 var a¹;
 if (true) {
   function a²() {} // hoisted
   a² = 5;
   a¹ = a²; // at the location of the declaration, the variable leaves the block      
   a² = 0;
  console.log(a²)
}
console.log(a¹);

En realidad, esto no es realmente parte de la especificación, es parte de la semántica de compatibilidad heredada de la web , por lo que no declare funciones dentro de bloques y no confíe en que este código se comporte de esta manera .

Esto también se explica aquí

Jonas Wilms
fuente
Pero, ¿por qué una vez que se alcanza la declaración de la función, la variable de bloque se copiará en la variable externa?
Chor
@Chor no, la especificación lo dice. No tengo ni idea de porqué.
Jonas Wilms