Vi känner till många jämförelseoperatorer från matematiken.
I JavaScript skrivs de så här:
- Greater/less than:
a > b
,a < b
. - Större/mindre än eller lika:
a >= b
,a <= b
. - Gränsar:
a >= b
,a <= b
. - Gränsar:
a == b
, observera att det dubbla likhetstecknet==
betyder likhetstestet, medan ett enkelta = b
betyder ett uppdrag. - Inte lika. I matematik är notationen
≠
, men i JavaScript skrivs det soma != b
.
I den här artikeln lär vi oss mer om olika typer av jämförelser, hur JavaScript gör dem, inklusive viktiga egenheter.
I slutet hittar du ett bra recept för att undvika ”JavaScript quirks”-relaterade problem.
Boolean är resultatet
Alla jämförelseoperatörer returnerar ett booleanskt värde:
-
true
– betyder ”ja”, ”korrekt” eller ”sanningen”. -
false
– betyder ”nej”, ”fel” eller ”inte sanningen”.
Till exempel:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
Ett jämförelseresultat kan tilldelas en variabel, precis som alla värden:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
Stringjämförelse
För att se om en sträng är större än en annan använder JavaScript den s.k. ”dictionary”- eller ”lexikografiska” ordningen.
Med andra ord jämförs strängar bokstav för bokstav.
Till exempel:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
Algoritmen för att jämföra två strängar är enkel:
- Genomföra det första tecknet i båda strängarna.
- Om det första tecknet från den första strängen är större (eller mindre) än den andra strängens, är den första strängen större (eller mindre) än den andra. Vi är klara.
- Och om båda strängarnas första tecken är lika långa, jämför de andra tecknen på samma sätt.
- Upprepa till slutet av någon av strängarna.
- Om båda strängarna slutar på samma längd, så är de lika långa. Annars är den längre strängen större.
I det första exemplet ovan får jämförelsen 'Z' > 'A'
ett resultat i det första steget.
Den andra jämförelsen 'Glow'
och 'Glee'
behöver fler steg eftersom strängar jämförs tecken för tecken:
-
G
är samma somG
. -
l
är samma soml
. -
o
är större äne
. Stanna här. Den första strängen är större.
Den jämförelsealgoritm som ges ovan är ungefär likvärdig med den som används i ordböcker eller telefonkataloger, men den är inte exakt likadan.
Till exempel spelar stor- och småbokstäver roll. En stor bokstav "A"
är inte lika med en liten bokstav "a"
. Vilken av dem är större? Den lilla bokstaven "a"
. Varför? Därför att det lilla tecknet har ett större index i den interna kodningstabell som JavaScript använder (Unicode). Vi återkommer till specifika detaljer och konsekvenser av detta i kapitlet Strings.
För jämförelse av olika typer
När värden av olika typer jämförs omvandlar JavaScript värdena till siffror.
Till exempel:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
För boolska värden blir true
till 1
och false
till 0
.
Till exempel:
alert( true == 1 ); // truealert( false == 0 ); // true
Det är möjligt att samtidigt:
- Två värden är lika.
- Ett av dem är
true
som boolean och det andra ärfalse
som boolean.
Till exempel:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
Från JavaScript:s synvinkel är detta resultat helt normalt. En jämlikhetskontroll konverterar värden med hjälp av den numeriska konverteringen (därför blir "0"
0
), medan den explicita Boolean
-konverteringen använder en annan uppsättning regler.
Strikt jämlikhet
En vanlig jämlikhetskontroll ==
har ett problem. Den kan inte skilja 0
från false
:
alert( 0 == false ); // true
Det samma händer med en tom sträng:
alert( '' == false ); // true
Detta händer eftersom operander av olika typer omvandlas till tal av likhetsoperatorn ==
. En tom sträng, precis som false
, blir en nolla.
Vad gör vi om vi vill skilja 0
från false
?
En strikt likhetsoperator ===
kontrollerar likheten utan typkonvertering.
Med andra ord, om a
och b
är av olika typer, returnerar a === b
omedelbart false
utan att försöka konvertera dem.
Låt oss prova det:
alert( 0 === false ); // false, because the types are different
Det finns också en operatör !==
för ”strikt icke-jämlikhet” som är analog med !=
.
Den strikta likhetsoperatorn är lite längre att skriva, men gör det uppenbart vad som händer och lämnar mindre utrymme för fel.
Sammanställning med null och odefinierat
Det finns ett icke-intuitivt beteende när null
eller undefined
jämförs med andra värden.
För en strikt jämlikhetskontroll ===
De här värdena är olika, eftersom vart och ett av dem är en annan typ.
alert( null === undefined ); // false
För en icke-strikt kontroll ==
Det finns en särskild regel. Dessa två är ett ”sött par”: de är lika med varandra (i betydelsen ==
), men inte med något annat värde.
alert( null == undefined ); // true
För matematisering och andra jämförelser < > <= >=
null/undefined
omvandlas till siffror: null
blir 0
, medan undefined
blir NaN
.
Nu ska vi se några roliga saker som händer när vi tillämpar dessa regler. Och, vad som är viktigare, hur man inte går i fällan med dem.
Skymt resultat: noll vs 0
Låt oss jämföra null
med en nolla:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Matematiskt sett är det märkligt. Det sista resultatet anger att ”null
är större än eller lika med noll”, så i en av jämförelserna ovan måste det vara true
, men båda är falska.
Anledningen är att en jämlikhetskontroll ==
och jämförelser > < >= <=
fungerar på olika sätt. Jämförelser omvandlar null
till ett tal och behandlar det som 0
. Det är därför (3) null >= 0
är sant och (1) null > 0
är falskt.
Å andra sidan är jämlikhetskontrollen ==
för undefined
och null
definierad så att de, utan några konverteringar, är lika med varandra och inte lika med något annat. Det är därför som (2) null == 0
är falsk.
En ojämförbar odefinierad
Värdet undefined
ska inte jämföras med andra värden:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
Varför ogillar den noll så mycket? Alltid falskt!
Vi får dessa resultat eftersom:
- Varför jämförelser
(1)
och(2)
gerfalse
eftersomundefined
omvandlas tillNaN
ochNaN
är ett speciellt numeriskt värde som gerfalse
för alla jämförelser. - Likahetskontrollen
(3)
returnerarfalse
eftersomundefined
endast är lika mednull
,undefined
och inget annat värde.
Undervik problem
Varför gick vi igenom dessa exempel? Bör vi komma ihåg dessa egenheter hela tiden? Tja, egentligen inte. Egentligen kommer dessa knepiga saker gradvis att bli bekanta med tiden, men det finns ett gediget sätt att undvika problem med dem:
- Behandla alla jämförelser med
undefined/null
utom den strikta jämlikheten===
med utomordentlig försiktighet. - Använd inte jämförelser
>= > < <=
med en variabel som kan varanull/undefined
, såvida du inte är riktigt säker på vad du gör. Om en variabel kan ha dessa värden ska du kontrollera dem separat.
Sammanfattning
- Varjeoperatorer för jämförelser returnerar ett boolskt värde.
- Strängar jämförs bokstav för bokstav i ”ordboksordning”.
- När värden av olika typer jämförs omvandlas de till tal (med undantag för en strikt jämlikhetskontroll).
- Värdena
null
ochundefined
är lika==
varandra och är inte lika med något annat värde. - Var försiktig när du använder jämförelser som
>
eller<
med variabler som ibland kan varanull/undefined
. Det är en bra idé att kontrolleranull/undefined
separat.