Logo JavaScript

Croire que « else if » est un mot-clé en JavaScript est une erreur

Flattr this!

En JS, on est souvent tenté de coder en utilisant le "else if". C'est vrai qu'après tout, ça marche. Mais, c'est une erreur ! "else if" n'existe pas en JS, c'est juste une erreur de lecture humaine.

Quand vous faites ça :

if (toto === titi) {
    ...
} else if (toto === tata) {
    ...
}

En réalité, vous faites ça :

if (toto === titi) {
    ...
} else {
    if (toto === tata) {
        ...
    }
}

C'est juste l'astuce qui fait que vous n’êtes pas obligés de mettre des accolades qui vous envoie en ligne droite dans le mur.

D'ailleurs, la MDN est très claire sur le sujet : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else#Description

La piège se situe alors ici :

if (toto === titi) {
    ...
} else if (toto === tata) {
    ...
} else if (toto === tutu) {
    ...
}

Où on pourrait croire qu'il y a 3 cas possibles comme un switch. Alors qu'en fait, on fait :

if (toto === titi) {
    ...
} else {
    if (toto === tata) {
        ...
    }
    else {
        if (toto === tutu) {
            ...
        }
    }
}

Ce qui n'est plus du tout pareil 😉

Flattr this!

A propos de Mathieu

Ingénieur développeur web dans la vente par correspondance B2B, adepte de nouvelles technologies et d'innovation. Vous pouvez aussi me retrouver sur Twitter @mathrobin
Cette entrée a été publiée dans JavaScript, avec comme mot(s)-clef(s) . Vous pouvez la mettre en favoris avec ce permalien.
  • Alexis Jacomy

    Intéressant. Mais en pratique, quand tu parles d’aller « en ligne droite dans le mur », tu penses à quoi? Plus précisément, qu’est-ce que ça change d’être dans des else imbriqués?

    • http://www.mathieurobin.com/ Mathieu

      J’ai complété l’article, j’avais effectivement oublié un exemple qui montre le problème de croire à l’existence de cette structure.

      • Alexis Jacomy

        A vrai dire, même là, je ne vois pas où est la différence.
        Pourrais tu décrire un cas pratique, où le résultat diffère entre les deux méchanismes?

        • http://www.mathieurobin.com/ Mathieu

          Il n’y aura pas de différence de comportement. Ni de performance. C’est seulement une erreur de croire que la structure existe. J’ai été un peu bourrin dans mon titre accrocheur :s

  • maarek_j

    Je ne vois pas où est l’erreur.
    Je suis d’accord pour dire que la plupart du temps on fait une « erreur de lecture humaine » quand on voit cette structure utilisé. Mais comme tu l’as dit ça fonctionne, et ça fait ce qu’on espère sans surprise aucune. Donc je ne vois pas ça comme une erreur, mais plutôt comme un raccourcie (ou une astuce).

    On retrouve cette astuce en C et en C++ aussi, et surement dans pleins d’autre languages, faut juste faire attention à l’indentation (comme expliqué dans l’article sur le MDN)

    • http://www.mathieurobin.com/ Mathieu

      J’avais oublié un exemple des problèmes potentiels que ça peut causer. Désolé. J’ai mis à jour l’article.

      • maarek_j

        J’avais bien conscience que la première structure est équivalente à la celle de ton dernière exemple, mais je ne vois toujours pas où est le problème.

        Chez moi cet exemple:

        [‘titi’, ‘tata’, ‘tutu’].forEach(function(toto) {
        if (toto === ‘titi’) {
        console.log(‘titi’);
        } else if (toto === ‘tata’) {
        console.log(‘tata’)
        } else if (toto === ‘tutu’) {
        console.log(‘tutu’)
        }
        });

        > titi
        > tata
        > tutu

        • http://www.mathieurobin.com/ Mathieu

          Et c’est normal. Mon titre accrocheur s’est retourné contre moi. Il n’y a pas d’erreur du à l’empilement, ni de perte de performances face à un switch. L’erreur est simplement de croire que la structure else if existe en tant que telle alors que c’est une interprétation de la lecture.
          Sinon, nous aurions le mot clé « elseif » par exemple.

  • Benjamin

    Hello,
    Ton article est intéressant, mais je ne vois pas bien le problème.
    Tu ne peux pas causer d’erreur, même en empilant les conditions, puisqu’on s’arrête la première fois que la condition est vraie. Le process n’est peut être pas un switch, mais le résultat est le même (sauf peut être en terme de performances…).
    J’ai mis un exemple ici : http://jsfiddle.net/Hu7eu/ peux tu essayer de lui faire avoir un comportement non désiré ?

    • http://www.mathieurobin.com/ Mathieu

      Mon titre accrocheur s’est retourné contre moi. Il n’y a pas d’erreur du à l’empilement, ni de perte de performances face à un switch. L’erreur est simplement de croire que la structure else if existe en tant que telle alors que c’est une interprétation de la lecture.
      Sinon, nous aurions le mot clé « elseif » par exemple.

  • Anon

    La découverte de ce problème fut douloureuse, et j’ai toujours pas compris pourquoi les projets ou j’utilisais naïvement cette méthode marchaient comme je voulais ^^

    • http://qosgof.fr/fosteb PA

      Car il n’y a pas de problème ? :)

    • http://www.mathieurobin.com/ Mathieu

      Parce qu’en soit, l’empilement ne pose pas de problème ni de différence de performances d’ailleurs.

    • Anon

      Du code qui marche tout seul même s’il est pas prévu pour ! Juste par la pensée !
      C’est ça la magie de noel la programmation !

  • http://qosgof.fr/fosteb PA

    Mathieu, je crois que tu te trompes.
    Essaye de faire un exemple où ça pose problème pour voir…

    • http://www.mathieurobin.com/ Mathieu

      Ah ça ne pose pas de problème de comportement. C’est juste une erreur de croire que la structure existe. C’était simplement pour mettre au clair ce petit détail du langage.

      • http://adrian.gaudebert.fr Adrian

        Mais, elle existe, la structure, puisque tu peux l’utiliser. Dans tous les langages de programmation qui implémentent un équivalent de « else if« , c’est la même chose. Comment est-ce que tu ferais un « else if«  si tu devais programmer un langage ?

      • http://qosgof.fr/fosteb PA

        Donc on va dans le mur, mais le mur ne fait pas mal ?
        Parfait.

        • http://www.mathieurobin.com/ Mathieu

          Oui, c’est un mur en mousse :)

      • http://log.winsos.net Plop

        Le titre de l’article est peut-être un peu exagéré alors : la *grosse* erreur.
        Parce que ok la structure n’existe pas en tant que telle mais bon si ça ne change rien à l’exécution…

        • http://www.mathieurobin.com/ Mathieu

          Oui, j’ai un peu honte d’avoir joué le jeu du titre accrocheur.

  • http://adrian.gaudebert.fr Adrian

    Ce que tu montres dans ton dernier exemple est parfaitement logique, et exactement ce qu’on attend d’un « else if« . Il n’y a aucun problème à utiliser ce mot-clé, aucun piège. La différence avec un switch est connue. En fait, je ne vois vraiment pas où tu veux en venir dans ce billet.

    • http://www.mathieurobin.com/ Mathieu

      L’idée est de montrer que non justement. T’as des langages où tu as « elseif » qui est un mot-clé réservé. Là tu profites seulement que tu peux ne pas déclarer les accolades si tu n’as qu’une seule instruction ou bloc d’instructions, contenu ici dans un if. Ce n’est en rien une erreur de code qui marchera une fois sur 10, c’est seulement une erreur de croire qu’elle existe.

      • http://adrian.gaudebert.fr Adrian

        HOLY S**T! J’ai compris où tu voulais en venir, et c’est bien vu !

        Par contre, n’hésite pas à éditer ton billet pour ajouter ses explications, parce sans ça ça me parait vraiment dur de comprendre ce que tu essayes de montrer.

        (Et je conseille un titre genre « else if n’existe pas en JavaScript », plus proche du contenu. )

        • http://www.mathieurobin.com/ Mathieu

          Oui, je vais changer le titre parce que là, j’ai un peu mardé 😉

      • Loic

        Je pige pas trop, si le mot-clef « elseif » existait, le comportement serait identique à « else if ».
        Et ton exemple est identique à un switch à condition que chaque condition du switch ait un break (et que l’ordre des conditions du switch ne bouge pas).

        En plus tu finis ton article en disant « Où on pourrait croire qu’il y a 3 cas possibles comme un switch. Alors qu’en fait, on fait… ». Non, tu as bien 3 cas, ce sont les 3 endroits marqués par des « … » dans ton exemple.

        • http://www.mathieurobin.com/ Mathieu

          Oui et non. Effectivement on a bien 3 cas. L’idée était surtout de montrer que le mot clé n’existe pas et que c’est un problème de lecture du code. On est d’accord qu’au niveau performances ou au niveau comportemental, ça ne change strictement rien.

  • Niamor36

    Salut Mathieu

    En fait, tu aurais pu aller un peu plus loin en ajoutant le cas :

    if ( a == true ) {
    ....
    } else if ( b == true ) {
    ....
    } else {
    ....
    }

    Effectivement, en javascript « else if » n’est pas un ‘mot clef’ en soit, dans d’autre langages, c’en est un « elseif ».
    Mais c’est une structure qui a une utilité logique, notammment lorsque mis en relation avec un ‘else’ par défaut.

    • http://www.mathieurobin.com/ Mathieu

      Ce cas était effectivement différent de ceux que j’ai présenté. Je ne dis pas de ne pas utiliser else if, mais je suggère de ne pas l’utiliser sous cette forme mais bien sous sa forme normale. En respectant donc l’utilisation des accolades. Ce n’est pas un mot clé ni un mot réservé. Donc il vaut mieux respecter les bonnes pratiques. Ne serait-ce que pour éviter les risques de confusion chez des personnes moins aguerries.

      • http://adrian.gaudebert.fr Adrian

        Alors là par contre, j’aimerais bien savoir en quoi utiliser « else if«  est une mauvaise pratique. Effectivement, ce n’est pas un mot-clé mais une astuce du langage qui mène au même résultat, mais je ne vois pas du tout pourquoi ça ne devrait pas être utilisé. Ça ne provoque aucun bug, aucune erreur de compréhension, aucun problème de performance.

        Oui, c’est intéressant de constater que le mot-clé « else if » n’existe pas. Non, il ne faut pas dire que c’est mal de l’utiliser, car ça ne l’est pas.

        Par ailleurs, la MDN ne dit aucunement que c’est une mauvaise pratique, elle explique simplement ce qui se passe en réalité.

        • http://www.mathieurobin.com/ Mathieu

          C’est une mauvaise pratique dans le sens où ne pas utiliser les accolades est une mauvaise pratique « de lisibilité ». C’est d’ailleurs une bonne pratique qui est souvent attendue dans les nomenclatures de bien des frameworks dans bien des langages.

          L’exemple de prendre la MDN comme référence est parfait pour l’illustrer. Si on est obligés de montrer finalement comment cela sera interprété une fois traduit en JavaScript « propre », c’est que ce n’est pas une forme naturelle, donc potentiellement source de soucis. Ici, de lisibilité. Enfin ça reste mon point de vue bien sûr.

  • http://www.magix-cms.com gtraxx

    Bonjour Mathieu,
    je ne peux te dire qu’une chose merci pour ce rappel de bonnes pratiques.
    il est vrai que son utilisation « fonctionne » mais il est préférable de l’éviter, autant le respecter dans la mesure du possible.

    • http://www.mathieurobin.com/ Mathieu

      Hello ! Merci, comme souvent, on est d’accord :)

Articles liés