Les fonctions internes en JavaScript sont-elles hissées? Comment les règles de portée s'appliquent-elles?

Je pensais que JavaScript n'a pas de portée de bloc, mais la portée de la fonction, et que les déclarations sont hiérisées de leur bloc au sommet de leurs fonctions parentales.

Toutefois, le code suivant ne fonctionne pas comme prévu:

function one(a) { console.log("one called for " + a); if (a == 1) { function inner(b) { console.log("inner called for " + b); } inner(123); } inner(456); } one(1); one(2); one(3); 

Le premier one(1); L'appel se déroule normalement, sans aucune erreur, mais l'exécution s'arrête lorsque le second one(2); est appelé.

Ce comportement est intuitif: la fonction inner n'est définie que si a==1 .

Mais comment est-il compatible avec les règles de portée / levage?

Je pensais que sa définition serait hissée au sommet de sa portée, en dehors du bloc if qui ne devrait avoir aucun effet!

Edit: voici les erreurs que je reçois:

Capture d'écran de la console Firefox montrant l'erreur

Le navigateur est Firefox. Fiddle ici.

 if (…) { function …() { … } } 

Est non valide ECMAScript. Les déclarations de fonction doivent être au niveau supérieur de la fonction ou des corps de programme, à l'intérieur des blocs, leur comportement dépend de l'implémentation . Firefox exécute cette déclaration de fonction conditionnellement, d'autres navigateurs le forcent comme une déclaration de fonction normale. Déplacez-le à l'extérieur de l'instruction if ou attribuez une expression de fonction.

La déclaration de l' inner est hissée au sommet de la fonction extérieure. Cependant, sa valeur n'est définie que si a == 1 .

Lorsque outer() est appelé avec une valeur différente, l'appel à l' inner(456) échoue comme inner est toujours défini à undefined .