Nous connaissons de nombreux opérateurs de comparaison issus des mathématiques.
En JavaScript, ils s'écrivent ainsi :
Supérieur/inférieur à : a > b
, a < b
.
Supérieur/inférieur ou égal : a >= b
, a <= b
.
Égal à : a == b
, veuillez noter le double signe d'égalité ==
signifie le test d'égalité, tandis qu'un simple a = b
signifie une affectation.
Pas égal : en mathématiques, la notation est ≠
, mais en JavaScript, elle s'écrit sous la forme a != b
.
Dans cet article, nous en apprendrons davantage sur les différents types de comparaisons, sur la manière dont JavaScript les effectue, ainsi que sur les particularités importantes.
À la fin, vous trouverez une bonne recette pour éviter les problèmes liés aux « bizarreries JavaScript ».
Tous les opérateurs de comparaison renvoient une valeur booléenne :
true
– signifie « oui », « correct » ou « la vérité ».
false
– signifie « non », « faux » ou « pas la vérité ».
Par exemple:
alerte( 2 > 1 ); // vrai (correct) alerte( 2 == 1 ); // faux (faux) alerte( 2 != 1 ); // vrai (correct)
Un résultat de comparaison peut être affecté à une variable, comme n'importe quelle valeur :
soit le résultat = 5 > 4 ; // assigne le résultat de la comparaison alerte( résultat ); // vrai
Pour voir si une chaîne est supérieure à une autre, JavaScript utilise l'ordre dit « dictionnaire » ou « lexicographique ».
En d’autres termes, les chaînes sont comparées lettre par lettre.
Par exemple:
alerte( 'Z' > 'A' ); // vrai alert( 'Glow' > 'Glee' ); // vrai alert( 'Abeille' > 'Être' ); // vrai
L'algorithme pour comparer deux chaînes est simple :
Comparez le premier caractère des deux chaînes.
Si le premier caractère de la première chaîne est supérieur (ou inférieur) à celui de l'autre chaîne, alors la première chaîne est supérieure (ou inférieure) à la seconde. Nous avons terminé.
Sinon, si les premiers caractères des deux chaînes sont identiques, comparez les seconds caractères de la même manière.
Répétez jusqu’à la fin de l’une ou l’autre chaîne.
Si les deux chaînes se terminent par la même longueur, alors elles sont égales. Sinon, la chaîne la plus longue est la plus grande.
Dans le premier exemple ci-dessus, la comparaison 'Z' > 'A'
aboutit à un résultat à la première étape.
La deuxième comparaison 'Glow'
et 'Glee'
nécessite plus d'étapes car les chaînes sont comparées caractère par caractère :
G
est identique à G
.
l
est le même que l
.
o
est supérieur à e
. Arrêtez ici. La première chaîne est plus grande.
Pas un vrai dictionnaire, mais un ordre Unicode
L'algorithme de comparaison donné ci-dessus est à peu près équivalent à celui utilisé dans les dictionnaires ou les annuaires téléphoniques, mais ce n'est pas exactement le même.
Par exemple, le cas compte. Une lettre majuscule "A"
n'est pas égale à la minuscule "a"
. Lequel est le plus grand ? Le "a"
minuscule. Pourquoi? Parce que le caractère minuscule a un indice plus grand dans la table de codage interne utilisée par JavaScript (Unicode). Nous reviendrons sur les détails spécifiques et les conséquences de cela dans le chapitre Chaînes.
Lors de la comparaison de valeurs de différents types, JavaScript convertit les valeurs en nombres.
Par exemple:
alerte( '2' > 1 ); // vrai, la chaîne '2' devient un chiffre 2 alerte( '01' == 1 ); // vrai, la chaîne '01' devient un chiffre 1
Pour les valeurs booléennes, true
devient 1
et false
devient 0
.
Par exemple:
alerte( true == 1 ); // vrai alerte( false == 0 ); // vrai
Une drôle de conséquence
Il est possible qu'en même temps :
Deux valeurs sont égales.
L’un d’eux est true
en tant que booléen et l’autre est false
en tant que booléen.
Par exemple:
soit a = 0 ; alert( Booléen(a) ); // FAUX soit b = "0" ; alerte( Booléen(b) ); // vrai alerte(a == b); // vrai!
Du point de vue de JavaScript, ce résultat est tout à fait normal. Un contrôle d'égalité convertit les valeurs à l'aide de la conversion numérique (d'où "0"
devient 0
), tandis que la conversion Boolean
explicite utilise un autre ensemble de règles.
Un contrôle d'égalité régulier ==
a un problème. Il ne peut pas différencier 0
de false
:
alerte( 0 == faux ); // vrai
La même chose se produit avec une chaîne vide :
alerte( '' == faux ); // vrai
Cela se produit parce que des opérandes de types différents sont convertis en nombres par l'opérateur d'égalité ==
. Une chaîne vide, tout comme false
, devient un zéro.
Que faire si l'on souhaite différencier 0
de false
?
Un opérateur d'égalité stricte ===
vérifie l'égalité sans conversion de type.
En d’autres termes, si a
et b
sont de types différents, alors a === b
renvoie immédiatement false
sans tenter de les convertir.
Essayons :
alerte( 0 === faux ); // faux, car les types sont différents
Il existe également un opérateur de « non-égalité stricte » !==
analogue à !=
.
L'opérateur d'égalité stricte est un peu plus long à écrire, mais rend évident ce qui se passe et laisse moins de place aux erreurs.
Il existe un comportement non intuitif lorsque null
ou undefined
sont comparés à d'autres valeurs.
Pour un contrôle d'égalité stricte ===
Ces valeurs sont différentes, car chacune d’elles est d’un type différent.
alert( null === non défini ); // FAUX
Pour un contrôle non strict ==
Il y a une règle spéciale. Ces deux-là forment un « doux couple » : ils sont égaux (au sens de ==
), mais pas d’autre valeur.
alerte( null == non défini ); // vrai
Pour les mathématiques et autres comparaisons < > <= >=
null/undefined
sont convertis en nombres : null
devient 0
, tandis que undefined
devient NaN
.
Voyons maintenant quelques choses amusantes qui se produisent lorsque nous appliquons ces règles. Et, plus important encore, comment ne pas tomber dans un piège avec eux.
Comparons null
avec un zéro :
alerte( null > 0 ); // (1) faux alerte( null == 0 ); // (2) faux alerte( null >= 0 ); // (3) vrai
Mathématiquement, c'est étrange. Le dernier résultat indique que « null
est supérieur ou égal à zéro », donc dans l'une des comparaisons ci-dessus, cela doit être true
, mais les deux sont faux.
La raison en est qu'un contrôle d'égalité ==
et des comparaisons > < >= <=
fonctionnent différemment. Les comparaisons convertissent null
en nombre, en le traitant comme 0
. C'est pourquoi (3) null >= 0
est vrai et (1) null > 0
est faux.
D'un autre côté, le contrôle d'égalité ==
pour undefined
et null
est défini de telle sorte que, sans aucune conversion, ils sont égaux et n'égalent rien d'autre. C'est pourquoi (2) null == 0
est faux.
La valeur undefined
ne doit pas être comparée à d'autres valeurs :
alerte( non défini > 0 ); // faux (1) alerte( non défini < 0 ); // faux (2) alerte( non défini == 0 ); // faux (3)
Pourquoi déteste-t-il autant zéro ? Toujours faux !
Nous obtenons ces résultats parce que :
Les comparaisons (1)
et (2)
renvoient false
car undefined
est converti en NaN
et NaN
est une valeur numérique spéciale qui renvoie false
pour toutes les comparaisons.
Le contrôle d'égalité (3)
renvoie false
car undefined
n'est égal qu'à null
, undefined
et à aucune autre valeur.
Pourquoi avons-nous passé en revue ces exemples ? Faut-il garder à l’esprit ces particularités à tout moment ? Eh bien, pas vraiment. En fait, ces choses délicates deviendront progressivement familières au fil du temps, mais il existe un moyen solide d'éviter les problèmes :
Traitez toute comparaison avec undefined/null
sauf la stricte égalité ===
avec un soin exceptionnel.
N'utilisez pas de comparaisons >= > < <=
avec une variable qui peut être null/undefined
, sauf si vous êtes vraiment sûr de ce que vous faites. Si une variable peut avoir ces valeurs, vérifiez-les séparément.
Les opérateurs de comparaison renvoient une valeur booléenne.
Les chaînes sont comparées lettre par lettre dans l’ordre du « dictionnaire ».
Lorsque des valeurs de différents types sont comparées, elles sont converties en nombres (à l'exclusion d'un contrôle d'égalité strict).
Les valeurs null
et undefined
sont égales ==
et ne sont égales à aucune autre valeur.
Soyez prudent lorsque vous utilisez des comparaisons telles que >
ou <
avec des variables qui peuvent parfois être null/undefined
. Vérifier séparément null/undefined
est une bonne idée.
importance : 5
Quel sera le résultat de ces expressions ?
5 > 4 "pomme" > "ananas" "2" > "12" non défini == nul non défini === nul nul == "n0n" nul === +"n0n"
5 > 4 → vrai "pomme" > "ananas" → faux "2" > "12" → vrai non défini == nul → vrai non défini === nul → faux null == "n0n" → faux null === +"n0n" → faux
Quelques-unes des raisons :
Évidemment, c'est vrai.
Comparaison de dictionnaire, donc fausse. "a"
est plus petit que "p"
.
Encore une fois, comparaison du dictionnaire, le premier caractère "2"
est supérieur au premier caractère "1"
.
Les valeurs null
et undefined
sont uniquement égales.
Une égalité stricte est stricte. Différents types des deux côtés conduisent à des erreurs.
Semblable à (4)
, null
n'est égal qu'à undefined
.
Stricte égalité des différents types.