Vi kender mange sammenligningsoperatorer fra matematikken.
I JavaScript skrives de således:
- Greater/less than:
a > b
,a < b
. - Større/mindre end eller lig med:
a > b
,a < b
:a >= b
,a <= b
. - Er lig med:
a >= b
,a <= b
. -
a == b
, bemærk det dobbelte lighedstegn==
betyder lighedstest, mens et enkelta = b
betyder en tildeling. - Ikke lige. I matematik er notationen
≠
, men i JavaScript skrives det soma != b
.
I denne artikel lærer vi mere om forskellige typer sammenligninger, hvordan JavaScript foretager dem, herunder vigtige særheder.
I slutningen finder du en god opskrift til at undgå “JavaScript quirks”-relaterede problemer.
Boolean er resultatet
Alle sammenligningsoperatører returnerer en booleanværdi:
-
true
– betyder “ja”, “korrekt” eller “sandheden”. -
false
– betyder “nej”, “forkert” eller “ikke sandheden”.
For eksempel:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
Et sammenligningsresultat kan tildeles en variabel ligesom enhver værdi:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
Sammenligning af strenge
For at se, om en streng er større end en anden, bruger JavaScript den såkaldte “ordbogs-” eller “leksikografiske” rækkefølge.
Med andre ord sammenlignes strenge bogstav for bogstav.
For eksempel:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
Algoritmen til at sammenligne to strenge er enkel:
- Sammenlign det første tegn i begge strenge.
- Hvis det første tegn fra den første streng er større (eller mindre) end den anden strengs tegn, så er den første streng større (eller mindre) end den anden. Vi er færdige.
- Hvis begge strenges første tegn er de samme, skal du sammenligne de andre tegn på samme måde.
- Gentag dette indtil slutningen af en af de to strenge.
- Hvis begge strenge slutter på samme længde, er de lige lange. Ellers er den længere streng større.
I det første eksempel ovenfor får sammenligningen 'Z' > 'A'
et resultat på det første trin.
Den anden sammenligning 'Glow'
og 'Glee'
kræver flere trin, da strengene sammenlignes tegn for tegn:
-
G
er det samme somG
. -
l
er det samme soml
. -
o
er større ende
. Stop her. Den første streng er større.
Sammenligningsalgoritmen ovenfor svarer nogenlunde til den, der bruges i ordbøger eller telefonbøger, men den er ikke helt den samme.
For eksempel har kasus betydning. Et stort bogstav "A"
er ikke lig med det lille bogstav "a"
. Hvilket af dem er størst? Det lille bogstav "a"
. Hvorfor? Fordi det lille bogstav har et større indeks i den interne kodningstabel, som JavaScript bruger (Unicode). Vi vender tilbage til specifikke detaljer og konsekvenser af dette i kapitlet Strings.
Sammenligning af forskellige typer
Når vi sammenligner værdier af forskellige typer, konverterer JavaScript værdierne til tal.
For eksempel:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
For boolske værdier bliver true
til 1
og false
til 0
.
For eksempel:
alert( true == 1 ); // truealert( false == 0 ); // true
Det er muligt, at på samme tid:
- To værdier er lige store.
- Den ene af dem er
true
som boolean og den anden erfalse
som boolean.
For eksempel:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
Fra JavaScript’s synspunkt er dette resultat helt normalt. En lighedskontrol konverterer værdier ved hjælp af den numeriske konvertering (derfor bliver "0"
til 0
), mens den eksplicitte Boolean
-konvertering bruger et andet sæt regler.
Strict equality
En almindelig lighedskontrol ==
har et problem. Den kan ikke skelne 0
fra false
:
alert( 0 == false ); // true
Det samme sker med en tom streng:
alert( '' == false ); // true
Dette sker, fordi operander af forskellig type konverteres til tal af lighedsoperatoren ==
. En tom streng bliver ligesom false
til et nul.
Hvad skal vi gøre, hvis vi gerne vil skelne 0
fra false
?
En streng lighedsoperator ===
kontrollerer ligheden uden typeomdannelse.
Med andre ord, hvis a
og b
er af forskellig type, så returnerer a === b
straks false
uden forsøg på at konvertere dem.
Lad os prøve det:
alert( 0 === false ); // false, because the types are different
Der findes også en “strict non-equality”-operator !==
analogt med !=
.
Den strenge lighedsoperator er lidt længere at skrive, men gør det tydeligt, hvad der foregår, og giver mindre plads til fejl.
Sammenligning med null og udefineret
Der er en ikke-intuitiv opførsel, når null
eller undefined
sammenlignes med andre værdier.
Ved en streng lighedskontrol ===
Disse værdier er forskellige, fordi de hver især er af en anden type.
alert( null === undefined ); // false
Ved en ikke-strengt kontrol ==
Der er en særlig regel. Disse to er et “sødt par”: De er lig hinanden (i betydningen ==
), men ikke nogen anden værdi.
alert( null == undefined ); // true
Til matematik og andre sammenligninger < > <= >=
null/undefined
omdannes til tal: null
bliver til 0
, mens undefined
bliver til NaN
.
Nu skal vi se nogle sjove ting, der sker, når vi anvender disse regler. Og, hvad der er vigtigere, hvordan man ikke falder i en fælde med dem.
Særligt resultat: nul vs 0
Lad os sammenligne null
med et nul:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Matematisk set er det mærkeligt. Det sidste resultat siger, at “null
er større end eller lig med nul”, så i en af sammenligningerne ovenfor må det være true
, men de er begge falske.
Grunden er, at en lighedskontrol ==
og sammenligninger > < >= <=
fungerer forskelligt. Sammenligninger konverterer null
til et tal og behandler det som 0
. Derfor er (3) null >= 0
sandt og (1) null > 0
falsk.
På den anden side er lighedskontrollen ==
for undefined
og null
defineret således, at de uden konverteringer er lig med hinanden og ikke er lig med noget andet. Derfor er (2) null == 0
falsk.
En usammenlignelig udefineret
Værdien undefined
bør ikke sammenlignes med andre værdier:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
Hvorfor kan den ikke lide nul så meget? Altid falsk!
Vi får disse resultater, fordi:
- Sammenligninger
(1)
og(2)
giverfalse
, fordiundefined
bliver konverteret tilNaN
, ogNaN
er en særlig numerisk værdi, som giverfalse
for alle sammenligninger. - Lighedskontrollen
(3)
returnererfalse
, fordiundefined
kun er lig mednull
,undefined
og ingen anden værdi.
Undgå problemer
Hvorfor gennemgik vi disse eksempler? Skal vi huske disse særheder hele tiden? Tja, egentlig ikke. Faktisk vil disse vanskelige ting efterhånden blive bekendt med tiden, men der er en solid måde at undgå problemer med dem på:
- Behandl enhver sammenligning med
undefined/null
undtagen den strenge lighed===
med usædvanlig forsigtighed. - Brug ikke sammenligninger
>= > < <=
med en variabel, som kan værenull/undefined
, medmindre du er helt sikker på, hvad du gør. Hvis en variabel kan have disse værdier, skal du kontrollere dem separat.
Summarum
- Sammenligningsoperatorer returnerer en boolsk værdi.
- Strenge sammenlignes bogstav for bogstav i “ordbogs”-rækkefølge.
- Når værdier af forskellige typer sammenlignes, bliver de konverteret til tal (med undtagelse af en streng lighedskontrol).
- Værdierne
null
ogundefined
er lig med==
hinanden og er ikke lig med nogen anden værdi. - Vær forsigtig, når du bruger sammenligninger som
>
eller<
med variabler, der lejlighedsvis kan værenull/undefined
. Det er en god idé at kontrollere fornull/undefined
separat.