We kennen veel vergelijkingsoperatoren uit de wiskunde.
In JavaScript worden ze als volgt geschreven:
- Groter/less than:
a > b
,a < b
. - Groter/minder dan of gelijk aan:
a >= b
,a <= b
. - Geëvenaard:
a == b
, let op: het dubbele gelijkheidsteken==
betekent de gelijkheidstoets, terwijl een enkelvoudigea = b
een toewijzing betekent. - Niet gelijk. In de wiskunde is de notatie
≠
, maar in JavaScript wordt het geschreven alsa != b
.
In dit artikel leren we meer over verschillende soorten vergelijkingen, hoe JavaScript ze maakt, inclusief belangrijke eigenaardigheden.
Aan het eind vind je een goed recept om “JavaScript quirks”-gerelateerde problemen te vermijden.
Boolean is het resultaat
Alle vergelijkingsoperatoren geven een boolean waarde terug:
-
true
– betekent “ja”, “juist” of “de waarheid”. -
false
– betekent “nee”, “fout” of “niet de waarheid”.
Voorbeeld:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
Een vergelijkingsresultaat kan worden toegewezen aan een variabele, net als elke andere waarde:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
Vergelijking van tekenreeksen
Om te zien of een tekenreeks groter is dan een andere, gebruikt JavaScript de zogenaamde “dictionary” of “lexicografische” volgorde.
Met andere woorden, tekenreeksen worden letter voor letter vergeleken.
Voorbeeld:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
Het algoritme om twee tekenreeksen te vergelijken is eenvoudig:
- Vergelijk het eerste teken van beide tekenreeksen.
- Als het eerste teken van de eerste string groter (of kleiner) is dan dat van de andere string, dan is de eerste string groter (of kleiner) dan de tweede. We zijn klaar.
- anders, als de eerste tekens van beide strings hetzelfde zijn, vergelijk dan de tweede tekens op dezelfde manier.
- Herhaal dit tot het einde van een van beide strings.
- Als beide strings op dezelfde lengte eindigen, dan zijn ze gelijk. Anders, de langere string is groter.
In het eerste voorbeeld hierboven, de vergelijking 'Z' > 'A'
krijgt tot een resultaat in de eerste stap.
De tweede vergelijking 'Glow'
en 'Glee'
heeft meer stappen nodig omdat strings karakter-voor-karakter worden vergeleken:
-
G
is hetzelfde alsG
. -
l
is hetzelfde alsl
. -
o
is groter dane
. Stop hier. De eerste string is groter.
Het hierboven gegeven vergelijkingsalgoritme is ruwweg gelijk aan dat in woordenboeken of telefoonboeken, maar het is niet precies hetzelfde.
Hoofdletter bijvoorbeeld doet er toe. Een hoofdletter "A"
is niet gelijk aan de kleine letter "a"
. Welke is groter? De kleine letter "a"
. Waarom? Omdat de kleine letter een grotere index heeft in de interne codeertabel die JavaScript gebruikt (Unicode). We komen terug op specifieke details en gevolgen hiervan in het hoofdstuk Strings.
Vergelijking van verschillende typen
Bij het vergelijken van waarden van verschillende typen converteert JavaScript de waarden naar getallen.
Bijvoorbeeld:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
Voor booleaanse waarden wordt true
1
en false
wordt 0
.
Voorbeeld:
alert( true == 1 ); // truealert( false == 0 ); // true
Het is mogelijk dat tegelijkertijd:
- Twee waarden zijn gelijk.
- Een ervan is
true
als een boolean en de andere isfalse
als een boolean.
Voorbeeld:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
Vanuit het oogpunt van JavaScript is dit resultaat heel normaal. Een gelijkheidscontrole converteert waarden met behulp van de numerieke conversie (dus "0"
wordt 0
), terwijl de expliciete Boolean
conversie een andere set regels gebruikt.
Strikte gelijkheid
Een reguliere gelijkheidscontrole ==
heeft een probleem. Het kan 0
niet onderscheiden van false
:
alert( 0 == false ); // true
Hetzelfde gebeurt met een lege string:
alert( '' == false ); // true
Dit gebeurt omdat operanden van verschillende typen worden geconverteerd naar getallen door de gelijkheidsoperator ==
. Een lege string wordt, net als false
, een nul.
Wat moeten we doen als we 0
willen onderscheiden van false
?
Een strikte gelijkheidsoperator ===
controleert de gelijkheid zonder type-omzetting.
Met andere woorden, als a
en b
van verschillende types zijn, dan geeft a === b
onmiddellijk false
terug zonder een poging om ze te converteren.
Laten we het eens proberen:
alert( 0 === false ); // false, because the types are different
Er is ook een “strict non-equality” operator !==
analoog aan !=
.
De strikte gelijkheid-operator is wat langer om te schrijven, maar maakt duidelijk wat er aan de hand is en laat minder ruimte voor fouten.
Vergelijking met null en undefined
Er is een niet-intuïtief gedrag wanneer null
of undefined
worden vergeleken met andere waarden.
Voor een strikte gelijkheidscontrole ===
Deze waarden zijn verschillend, omdat ze elk een ander type zijn.
alert( null === undefined ); // false
Voor een niet-strikte controle==
Er is een speciale regel. Deze twee zijn een “lief paar”: ze zijn gelijk aan elkaar (in de zin van ==
), maar niet aan een andere waarde.
alert( null == undefined ); // true
Voor wiskunde en andere vergelijkingen < > <= >=
null/undefined
worden omgezet in getallen: null
wordt 0
, terwijl undefined
NaN
wordt.
Nu zullen we eens wat grappige dingen zien die gebeuren als we deze regels toepassen. En, wat belangrijker is, hoe we er niet mee in de val lopen.
Raar resultaat: null vs 0
Laten we null
eens vergelijken met een nul:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Mathematisch is dat vreemd. In het laatste resultaat staat dat “null
groter is dan of gelijk aan nul”, dus in een van de vergelijkingen hierboven moet het true
zijn, maar ze zijn allebei onwaar.
De reden is dat een gelijkheidscontrole ==
en vergelijkingen > < >= <=
verschillend werken. Vergelijkingen zetten null
om in een getal, en behandelen het als 0
. Daarom is (3) null >= 0
waar en (1) null > 0
onwaar.
Aan de andere kant is de gelijkheidscontrole ==
voor undefined
en null
zo gedefinieerd dat ze, zonder enige conversie, aan elkaar gelijk zijn en niet aan iets anders. Daarom is (2) null == 0
onwaar.
Een onvergelijkbare ongedefinieerde
De waarde undefined
mag niet worden vergeleken met andere waarden:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
Waarom heeft het zo’n hekel aan nul? Altijd onwaar!
We krijgen deze resultaten omdat:
- Vergelijkingen
(1)
en(2)
gevenfalse
terug omdatundefined
wordt omgezet inNaN
enNaN
is een speciale numerieke waarde diefalse
teruggeeft voor alle vergelijkingen. - De gelijkheidscontrole
(3)
retourneertfalse
omdatundefined
alleen gelijk is aannull
,undefined
, en geen andere waarde.
Vermijd problemen
Waarom hebben we deze voorbeelden doorgenomen? Moeten we deze eigenaardigheden altijd onthouden? Wel, niet echt. Eigenlijk zullen deze lastige dingen gaandeweg vertrouwd raken, maar er is een degelijke manier om problemen ermee te vermijden:
- Behandel elke vergelijking met
undefined/null
behalve de strikte gelijkheid===
met uitzonderlijke voorzichtigheid. - Gebruik geen vergelijkingen
>= > < <=
met een variabele dienull/undefined
kan zijn, tenzij u echt zeker weet wat u doet. Als een variabele deze waarden kan hebben, controleer er dan apart op.
Samenvatting
- Vergelijkingsoperatoren geven een boolean waarde terug.
- Strings worden letter-voor-letter vergeleken in de “dictionary” volgorde.
- Wanneer waarden van verschillende typen worden vergeleken, worden ze geconverteerd naar getallen (met uitzondering van een strikte gelijkheidscontrole).
- De waarden
null
enundefined
zijn==
gelijk aan elkaar en zijn niet gelijk aan een andere waarde. - Wees voorzichtig bij het gebruik van vergelijkingen zoals
>
of<
met variabelen die somsnull/undefined
kunnen zijn. Afzonderlijk controleren opnull/undefined
is een goed idee.