Cunoaștem mulți operatori de comparație din matematică.
În JavaScript se scriu astfel:
- Mai mare/mai mic decât:
a > b
,a < b
. - Mai mare/mai mic decât sau egal:
a >= b
,a <= b
. - Egal:
a == b
, rețineți că semnul dublu de egalitate==
înseamnă testul de egalitate, în timp ce unul singura = b
înseamnă o atribuire. - Nu este egal. În matematică notația este
≠
, dar în JavaScript se scriea != b
.
În acest articol vom afla mai multe despre diferite tipuri de comparații, cum le face JavaScript, inclusiv particularități importante.
La sfârșit veți găsi o rețetă bună pentru a evita problemele legate de „ciudățeniile JavaScript”.
Boolean este rezultatul
Toți operatorii de comparație returnează o valoare booleană:
-
true
– înseamnă „da”, „corect” sau „adevărul”. -
false
– înseamnă „nu”, „greșit” sau „nu este adevărul”.
De exemplu:
alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)
Rezultatul unei comparații poate fi atribuit unei variabile, la fel ca orice valoare:
let result = 5 > 4; // assign the result of the comparisonalert( result ); // true
Compararea șirurilor de caractere
Pentru a vedea dacă un șir de caractere este mai mare decât altul, JavaScript folosește așa-numita ordine „dicționară” sau „lexicografică”.
Cu alte cuvinte, șirurile de caractere sunt comparate literă cu literă.
De exemplu:
alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true
Algoritmul de comparare a două șiruri de caractere este simplu:
- Comparați primul caracter al ambelor șiruri.
- Dacă primul caracter din primul șir este mai mare (sau mai mic) decât cel al celuilalt șir, atunci primul șir este mai mare (sau mai mic) decât al doilea. Am terminat.
- În caz contrar, dacă primele caractere ale ambelor șiruri sunt identice, comparați în același mod și al doilea caracter.
- Repetați până la sfârșitul oricăruia dintre șiruri.
- Dacă ambele șiruri se termină la aceeași lungime, atunci ele sunt egale. În caz contrar, șirul mai lung este mai mare.
În primul exemplu de mai sus, comparația 'Z' > 'A'
ajunge la un rezultat la primul pas.
În a doua comparație 'Glow'
și 'Glee'
este nevoie de mai mulți pași, deoarece șirurile sunt comparate caracter cu caracter:
-
G
este la fel caG
. -
l
este la fel cal
. -
o
este mai mare decâte
. Opriți-vă aici. Primul șir de caractere este mai mare.
Algoritmul de comparație dat mai sus este aproximativ echivalent cu cel folosit în dicționare sau în listele de telefon, dar nu este exact același.
De exemplu, contează majusculele. O literă majusculă "A"
nu este egală cu minuscula "a"
. Care dintre ele este mai mare? Litera minusculă "a"
. De ce? Pentru că caracterul minuscul are un indice mai mare în tabelul intern de codificare pe care îl folosește JavaScript (Unicode). Vom reveni asupra detaliilor specifice și consecințelor acestui lucru în capitolul Șiruri de caractere.
Compararea diferitelor tipuri
Când comparăm valori de tipuri diferite, JavaScript convertește valorile în numere.
De exemplu:
alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1
Pentru valorile booleene, true
devine 1
și false
devine 0
.
De exemplu:
alert( true == 1 ); // truealert( false == 0 ); // true
Este posibil ca în același timp:
- Două valori să fie egale.
- Una dintre ele este
true
ca boolean și cealaltă estefalse
ca boolean.
De exemplu:
let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!
Din punctul de vedere al lui JavaScript, acest rezultat este destul de normal. O verificare a egalității convertește valorile folosind conversia numerică (prin urmare, "0"
devine 0
), în timp ce conversia explicită Boolean
folosește un alt set de reguli.
Egalitate strictă
O verificare obișnuită a egalității ==
are o problemă. Nu poate diferenția 0
de false
:
alert( 0 == false ); // true
Același lucru se întâmplă cu un șir gol:
alert( '' == false ); // true
Acest lucru se întâmplă deoarece operanzii de tipuri diferite sunt convertiți în numere de către operatorul de egalitate ==
. Un șir de caractere gol, la fel ca false
, devine un zero.
Ce să facem dacă am dori să diferențiem 0
de false
?
Un operator de egalitate strictă ===
verifică egalitatea fără conversie de tip.
Cu alte cuvinte, dacă a
și b
sunt de tipuri diferite, atunci a === b
returnează imediat false
fără o încercare de a le converti.
Să încercăm:
alert( 0 === false ); // false, because the types are different
Există, de asemenea, un operator de „neegalitate strictă” !==
analog cu !=
.
Operatorul de egalitate strictă este un pic mai lung de scris, dar face evident ce se întâmplă și lasă mai puțin loc pentru erori.
Comparare cu null și undefined
Există un comportament neintuitiv atunci când null
sau undefined
sunt comparate cu alte valori.
Pentru o verificare strictă a egalității ===
Aceste valori sunt diferite, deoarece fiecare dintre ele este de un tip diferit.
alert( null === undefined ); // false
Pentru o verificare non-strictă ==
Există o regulă specială. Aceste două sunt un „cuplu dulce”: ele sunt egale între ele (în sensul lui ==
), dar nu și orice altă valoare.
alert( null == undefined ); // true
Pentru matematică și alte comparații < > <= >=
null/undefined
sunt convertite în numere: null
devine 0
, în timp ce undefined
devine NaN
.
Acum să vedem câteva lucruri amuzante care se întâmplă atunci când aplicăm aceste reguli. Și, ceea ce este mai important, cum să nu cădem în capcană cu ele.
Rezultat ciudat: nul vs 0
Să comparăm null
cu un zero:
alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true
Matematic, este ciudat. Ultimul rezultat afirmă că „null
este mai mare sau egal cu zero”, deci în una dintre comparațiile de mai sus trebuie să fie true
, dar ambele sunt false.
Motivul este că o verificare a egalității ==
și comparațiile > < >= <=
funcționează diferit. Comparațiile convertesc null
într-un număr, tratându-l ca pe 0
. Acesta este motivul pentru care (3) null >= 0
este adevărat și (1) null > 0
este fals.
Pe de altă parte, verificarea egalității ==
pentru undefined
și null
este definită astfel încât, fără nicio conversie, ele sunt egale între ele și nu sunt egale cu nimic altceva. De aceea, (2) null == 0
este fals.
Un incomparabil nedefinit
Valoarea undefined
nu ar trebui comparată cu alte valori:
alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)
De ce îi displace atât de mult zero? Întotdeauna fals!
Avem aceste rezultate deoarece:
- Comparațiile
(1)
și(2)
returneazăfalse
deoareceundefined
este convertit înNaN
șiNaN
este o valoare numerică specială care returneazăfalse
pentru toate comparațiile. - Verificarea egalității
(3)
returneazăfalse
deoareceundefined
este egală doar cunull
,undefined
și nicio altă valoare.
Evitați problemele
De ce am trecut peste aceste exemple? Ar trebui să ne amintim tot timpul aceste particularități? Ei bine, nu prea. De fapt, aceste lucruri înșelătoare vor deveni treptat familiare în timp, dar există o modalitate solidă de a evita problemele cu ele:
- Tratați orice comparație cu
undefined/null
, cu excepția egalității stricte===
, cu o atenție excepțională. - Nu folosiți comparații
>= > < <=
cu o variabilă care poate finull/undefined
, decât dacă sunteți foarte siguri de ceea ce faceți. Dacă o variabilă poate avea aceste valori, verificați-le separat.
Rezumat
- Operatorii de comparare returnează o valoare booleană.
- Circuitele sunt comparate literă cu literă în ordinea „dicționarului”.
- Când sunt comparate valori de tipuri diferite, acestea sunt convertite în numere (cu excepția unei verificări stricte a egalității).
- Valorile
null
șiundefined
sunt egale==
între ele și nu sunt egale cu nici o altă valoare. - Fiți atenți când folosiți comparații precum
>
sau<
cu variabile care ocazional pot finull/undefined
. Verificarea pentrunull/undefined
separat este o idee bună.
.