confus à propos de la déclaration de fonction dans {}

18

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

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

J'ai vu le code ci-dessus, une fonction est déclarée dans {}. Je pense qu'il imprimerait 0 0, mais il imprime 0 5

Marcus Lee
la source
Est-ce que cela répond à votre question? Quelle est la sémantique précise des fonctions de niveau bloc dans ES6?
Jonas Wilms
1
En mode strict, il se connecte 0 undefined.
CertainPerformance
@certainPerformance bien, c'est explicable, mais je n'arrive pas à expliquer cela a = 5laisse le bloc. Selon bergi dans la dupe, function asera hissé.
Jonas Wilms
2
Il semble que la variable de bloc de portée locale soit copiée dans le bloc externe lorsqu'elle atteint la déclaration de fonction.
Jonas Wilms

Réponses:

13

Les événements suivants se produisent:

(1) Il existe deux déclarations de variables a, une à l'intérieur du bloc et une à l'extérieur de celui-ci.

(2) La déclaration de fonction est hissée et liée à la variable des blocs internes.

(3) a = 5est atteint, ce qui remplace la variable de bloc.

(4) la déclaration de fonction est atteinte et la variable de bloc est copiée dans la variable externe. Les deux ont maintenant 5 ans.

(5) a = 0est atteint, ce qui remplace la variable de bloc. La variable externe n'est pas affectée par cela.

 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 fait, cela ne fait pas vraiment partie de la spécification, il fait partie de la sémantique de compatibilité héritée du Web , donc ne déclarez pas de fonctions à l'intérieur des blocs et ne comptez pas sur ce code pour vous comporter de cette façon .

Ceci est également expliqué ici

Jonas Wilms
la source
Mais pourquoi une fois la déclaration de fonction atteinte, la variable de bloc sera copiée dans la variable externe?
Chor
@Chor non, la spécification le dit. Je ne sais pas pourquoi.
Jonas Wilms du