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í