170 votes

Pourquoi un retour dans `finally` prévaut-il sur `try` ?

Comment fonctionne une déclaration de retour dans un bloc try/catch ?

function example() {
    try {
        return true;
    }
    finally {
        return false;
    }
}

Je m'attends à ce que la sortie de cette fonction soit true mais au lieu de cela, c'est false ¡!

2 votes

Pour les autres, faites le retour false dans le bloc catch, pas finally.

157voto

annakata Points 42676

Enfin siempre s'exécute. C'est à cela qu'il sert, ce qui signifie que sa valeur de retour est utilisée dans votre cas.

Vous devez modifier votre code pour qu'il ressemble à ceci :

function example() { 
    var returnState = false; // initialization value is really up to the design
    try { 
        returnState = true; 
    } 
    catch {
        returnState = false;
    }
    finally { 
        return returnState; 
    } 
} 

D'une manière générale, il ne faut jamais avoir plus d'une déclaration de retour dans une fonction, ce qui explique ce genre de choses.

95 votes

Je dirais que le fait d'avoir plus d'une déclaration de retour n'est pas toujours mauvais. stackoverflow.com/questions/36707/ pour plus de discussion.

12 votes

Je ne suis pas d'accord non plus sur la règle du retour unique. Vous ne devriez jamais retourner de finally, cependant (en C#, ce n'est même pas autorisé).

0 votes

@erikkallen - c'est un bon point. Un retour en dehors du bloc T-C-F serait le mieux mais l'exemple de code serait un peu forcé :)

69voto

livibetter Points 3862

Selon la norme ECMA-262 (5ed, décembre 2009), en pages 96 :

La production TryStatement : try Block Finally est évalué comme suit :

  1. Soit B le résultat de l'évaluation de Block.
  2. Soit F le résultat de l'évaluation de Finally.
  3. Si le type F.est normal, renvoyer B.
  4. Retour F.

Et à partir de la page 36 :

Le type Completion est utilisé pour expliquer le comportement des déclarations ( break , continue , return y throw ) qui effectuent des transferts de contrôle non locaux. Les valeurs du type Completion sont des triples de la forme (type, valeur, cible) , donde type est l'un des normal , break , continue , return ou throw , valeur est une valeur quelconque du langage ECMAScript ou vide, et cible est un identifiant ECMAScript quelconque ou vide.

Il est clair que return false définirait le type d'achèvement de enfin como retourner qui provoquent try ... finally à faire 4. Retour F .

6 votes

Après avoir lu toutes sortes de réponses "fondamentalement correctes mais en quelque sorte floues et non explicites" à cette question, celle-ci lui a donné un sens. L'élément clé était que ce qui "se passe" à la fin du try+catch (return ou throw ou simplement le flux normal) est mémorisé pendant qu'il exécute la partie finally et qu'il ne se produit réellement que si rien ne se passe à la fin de finally.

24voto

GenericTypeTea Points 27689

Lorsque vous utilisez finally tout code contenu dans ce bloc est exécuté avant la sortie de la méthode. Comme vous utilisez un retour dans le bloc finally il appelle return false et remplace la précédente return true dans le try bloc.

(La terminologie n'est peut-être pas tout à fait correcte).

3voto

anishMarokey Points 6895

La raison pour laquelle vous obtenez des faux est que vous êtes retourné dans un bloc finally. le bloc finally doit toujours s'exécuter. donc votre return true les changements apportés à return false

function example() {
    try {
        return true;
    }
    catch {
        return false;
    }
}

1voto

Manoj Govindan Points 24030

Pour autant que je sache, le finally bloc siempre s'exécute, indépendamment du fait que vous ayez une return déclaration à l'intérieur try ou non. Ainsi, vous obtenez la valeur renvoyée par la fonction return dans le bloc final.

Je l'ai testé avec Firefox 3.6.10 et Chrome 6.0.472.63, tous deux sous Ubuntu. Il est possible que ce code se comporte différemment dans d'autres navigateurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X