Logo JavaScript

Message JSLint – Expected ‘!==’ and instead saw ‘!=’.

Flattr this!

Dans la série des messages JSLint, je continue avec celui-ci :

Expected '!==' and instead saw '!='.

Équivalent aussi à ce message :

Expected '===' and instead saw '=='.

Cause

Prenons pour exemple ce code :

if(toto != titi) {
    // corps
}

Second exemple

if (toto == titi) {
    // corps
}

Le problème ici est de faire confiance à JavaScript pour la comparaison des données. C'est à dire que là vous vérifiez que la valeur est la même mais sans tenir compte du type de données. Un peu comme si vous couriez tout nu sur le périphérique parisien avec les yeux bandés et les oreilles bouchées. En gros, ça va vous péter au nez et ça va faire mal.

Exemple

Par exemple, avec la double égalité, ceci est vrai :

' \t\r\n' == 0

Alors que vous pouvez le voir à l'oeil nu, c'est évidement faux. Dans le genre, Brian Leroux avait fait une très belle démo nommée "wtfJS" à DotJS et a construit ce site éponyme http://wtfjs.com/

La solution

Systématiquement (ou presque) vous assurez de bien vérifier de façon stricte vos données. C'est à dire en n'utilisant (presque) jamais la double égalité ou la différence simple. Mais la triple égalité ou la double comparaison dans la différence. Comme ceci :

if(toto !== titi) {
    // corps
}

Et

if (toto === titi) {
    // corps
}

Ce n'est pas toujours simple d'être sûr de son coup mais au moins vous pourrez être absolument sûr de ce que vous vérifiez.

Bonus

Cette règle existe d'ailleurs dans d'autres langages.

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.
  • check_ca


    var toto = 13;
    var titi = 42;
    if(toto != titi) {
    // corps
    }

    Si j’écris ce code, est-ce que c’est comme si je courais « tout nu sur le périphérique parisien avec les yeux bandés et les oreilles bouchées » ? Non. Car en tant que développeur qui développe son propre code, je sais ce que je fais.

    Maintenant, supposons que j’ai fait une super fonction que je veux que toute la planète utilise car elle est vraiment top ! La voici :

    function jQueryKiller(toto, titi) {
    if(toto != titi) {
    // corps
    }
    }

    Là, c’est au développeur qui va utiliser ma super fonction jQueryKiller de faire attention à ne pas passer n’importe quoi en paramètre de celle-ci. est-ce que l’utilisation de « !== » à la place de « != » va résoudre ce problème ? Non, car si le développeur se plante, dans les 2 cas, la fonction ne fonctionnera pas comme prévue. Pour résoudre ce problème il faut écrire de la doc pour qu’il sache comment utiliser cette fonction correctement et il faut inciter le développeur à lire cette doc. S’il ne la lit pas, alors là, ça sera comme si il courait « tout nu sur le périphérique parisien avec les yeux bandés et les oreilles bouchées » (notons au passage que ça serait presqu’aussi dangereux sur le périphérique de Rennes).

    Conclusion, ne soyez pas systématique au risque de tomber dans ce pattern et utilisez votre cerveau quand JsLint n’est pas content, d’autant plus que JsLint est connu pour être très pédant…

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

      On est d’accord sur le coté pédant et carrément obsessionnel de JsLint. Mais justement, valider là dessus me permet de garantir une qualité maximisée. Et accessoirement, même en écrivant ton propre code, tu n’es pas toujours sur des comparaisons que tu feras. Si les variables comparées ne sont pas exposées (via des input par exemple ou via une fonction partagée comme tu le proposes) là oui, il est peu probable qu’il soit utile de vérifier aussi les types. Mais des que c’est exposé tu prends des risques.
      D’ailleurs je ne suis pas du tout d’accord avec toi sur le fait que c’est au développeur et à lui seul qui utilise ta fonction de faire attention. Dans ce cas, autant virer la comparaison et directement lui demander de s’assurer que tous les paramètres sont ceux que tu attends.
      Donc au lieu de faire
      function jQueryKiller(toto, titi) {
      if(toto != titi) {
      // corps
      }
      }

      Tu demanderais donc carrément
      function jQueryKiller(toto, titi) {
      // corps
      }
      if(toto !== titi) {
      jQueryKiller(toto, titi);
      }
      Ce qui ne me semble pas envisageable.

      • check_ca

        > Si les variables comparées ne sont pas exposées (via des input par exemple ou via une fonction partagée comme tu le proposes) là oui, il est peu probable qu’il soit utile de vérifier aussi les types. Mais des que c’est exposé tu prends des risques.
        Ca, concrètement, c’est 99% le cas dans mon code.

        Je suis aussi d’accord pour virer le test de la fonction si besoin car c’est pour ça que je prend la peine d’écrire de la doc. De ce fait, je ne met jamais de test de pré/post condition dans mon code, car une fois la qualif terminée, il faudrait le supprimer (à la rigueur je veux bien faire de l’AOP pendant le dev’ s’il le faut).

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

          On n’est donc pas du tout d’accord sur la façon dont doit travailler quelqu’un qui expose des méthodes. J’essaie au maximum et de plus en plus de faire des tests de pré/post-conditions. Même sur des trucs complètement improbables. Héritage de ma formation quand je faisais de l’embarqué et je considère encore les environnements des navigateurs comme trop instable pour qu’on se permette d’ignorer ces tests. L’altération volontaire ou non des données et des comportements est trop probable pour se le permettre.

  • Jean-Noël

    Mathieu,

    C’est assez drôle ton article puisque j’étais justement en train de chercher pourquoi 1 == 1 retourne true et pourquoi 1 === 1 retourne false. Qu’entends-tu par type de données ?
    As-tu un exemple concrêt d’un cas qui donne raison à === ?

    Merci,

    Jean-Noël

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

      Le type de données, c’est tout simplement si c’est un nombre, une chaîne de caractères ou encore un objet par exemple. En JavaScript, 1==1, « 1 »==1, 1===1 mais « 1 »! ==1. 1 correspond au nombre 1, alors que « 1 » correspond à la chaîne de caractères contenant 1. Si tu utilises ==, JavaScript va automatiquement essayer de transformer le type de l’un ou l’autre pour essayer de trouver l’égalité. Avec ===, il va les comparer telles qu’elles sont. Comme un nombre ne peut pas être une chaîne de caractères, leur comparaison sera forcément fausse d’avance. Est-ce que ça répond bien à ta question ?
      Bonne soirée et bon réveillon en tout cas

Articles liés