Confronti

author
5 minutes, 45 seconds Read

Conosciamo molti operatori di confronto dalla matematica.

In JavaScript sono scritti così:

  • Maggiore/meno di: a > b, a < b.
  • Maggiore/meno che o uguale: a >= b, a <= b.
  • Equale: a == b, si noti che il doppio segno di uguaglianza == indica il test di uguaglianza, mentre uno singolo a = b indica un’assegnazione.
  • Non è uguale. In matematica la notazione è , ma in JavaScript si scrive a != b.

In questo articolo impareremo di più sui diversi tipi di confronto, come JavaScript li fa, incluse importanti peculiarità.

Alla fine troverete una buona ricetta per evitare problemi legati alle “stranezze di JavaScript”.

Booleano è il risultato

Tutti gli operatori di confronto restituiscono un valore booleano:

  • true – significa “sì”, “corretto” o “la verità”.
  • false – significa “no”, “sbagliato” o “non la verità”.

Per esempio:

alert( 2 > 1 ); // true (correct)alert( 2 == 1 ); // false (wrong)alert( 2 != 1 ); // true (correct)

Un risultato di confronto può essere assegnato a una variabile, proprio come qualsiasi valore:

let result = 5 > 4; // assign the result of the comparisonalert( result ); // true

Confronto tra stringhe

Per vedere se una stringa è maggiore di un’altra, JavaScript usa il cosiddetto ordine “dizionario” o “lessicografico”.

In altre parole, le stringhe sono confrontate lettera per lettera.

Per esempio:

alert( 'Z' > 'A' ); // truealert( 'Glow' > 'Glee' ); // truealert( 'Bee' > 'Be' ); // true

L’algoritmo per confrontare due stringhe è semplice:

  1. Compara il primo carattere di entrambe le stringhe.
  2. Se il primo carattere della prima stringa è maggiore (o minore) di quello dell’altra stringa, allora la prima stringa è maggiore (o minore) della seconda. Abbiamo finito.
  3. Altrimenti, se i primi caratteri di entrambe le stringhe sono uguali, confrontare i secondi caratteri allo stesso modo.
  4. Ripetere fino alla fine di entrambe le stringhe.
  5. Se entrambe le stringhe finiscono alla stessa lunghezza, allora sono uguali. Altrimenti, la stringa più lunga è maggiore.

Nel primo esempio sopra, il confronto 'Z' > 'A' arriva ad un risultato al primo passo.

Il secondo confronto 'Glow' e 'Glee' ha bisogno di più passi perché le stringhe sono confrontate carattere per carattere:

  1. G è uguale a G.
  2. l è uguale a l.
  3. o è maggiore di e. Fermati qui. La prima stringa è maggiore.
Non un vero dizionario, ma l’ordine Unicode

L’algoritmo di confronto dato sopra è approssimativamente equivalente a quello usato nei dizionari o negli elenchi telefonici, ma non è esattamente lo stesso.

Per esempio, il caso conta. Una lettera maiuscola "A" non è uguale alla minuscola "a". Quale è più grande? La minuscola "a". Perché? Perché il carattere minuscolo ha un indice maggiore nella tabella di codifica interna che JavaScript usa (Unicode). Torneremo ai dettagli specifici e alle conseguenze di questo nel capitolo Stringhe.

Confronto di tipi diversi

Quando si confrontano valori di tipi diversi, JavaScript converte i valori in numeri.

Per esempio:

alert( '2' > 1 ); // true, string '2' becomes a number 2alert( '01' == 1 ); // true, string '01' becomes a number 1

Per valori booleani, true diventa 1 e false diventa 0.

Per esempio:

alert( true == 1 ); // truealert( false == 0 ); // true

Una conseguenza divertente

È possibile che allo stesso tempo:

  • Due valori siano uguali.
  • Uno di essi è true come booleano e l’altro è false come booleano.

Per esempio:

let a = 0;alert( Boolean(a) ); // falselet b = "0";alert( Boolean(b) ); // truealert(a == b); // true!

Dal punto di vista di JavaScript, questo risultato è abbastanza normale. Un controllo di uguaglianza converte i valori usando la conversione numerica (quindi "0" diventa 0), mentre la conversione esplicita Boolean usa un altro insieme di regole.

Uguaglianza rigorosa

Un regolare controllo di uguaglianza == ha un problema. Non può differenziare 0 da false:

alert( 0 == false ); // true

La stessa cosa accade con una stringa vuota:

alert( '' == false ); // true

Questo accade perché operandi di tipo diverso sono convertiti in numeri dall’operatore di uguaglianza ==. Una stringa vuota, proprio come false, diventa uno zero.

Come fare se vogliamo differenziare 0 da false?

Un operatore di uguaglianza rigoroso === controlla l’uguaglianza senza conversione di tipo.

In altre parole, se a e b sono di tipo diverso, allora a === b restituisce immediatamente false senza un tentativo di conversione.

Proviamolo:

alert( 0 === false ); // false, because the types are different

C’è anche un operatore “strict non-equality” !== analogo a !=.

L’operatore di uguaglianza rigorosa è un po’ più lungo da scrivere, ma rende ovvio cosa sta succedendo e lascia meno spazio agli errori.

Confronto con null e undefined

C’è un comportamento non intuitivo quando null o undefined sono confrontati con altri valori.

Per un controllo di uguaglianza rigoroso===

Questi valori sono diversi, perché ognuno di loro è un tipo diverso.

alert( null === undefined ); // false

Per un controllo non rigoroso==

C’è una regola speciale. Questi due sono una “dolce coppia”: sono uguali tra loro (nel senso di ==), ma non qualsiasi altro valore.

alert( null == undefined ); // true

per la matematica e altri confronti< > <= >=

null/undefined sono convertiti in numeri: null diventa 0, mentre undefined diventa NaN.

Ora vediamo alcune cose divertenti che accadono quando applichiamo queste regole. E, cosa più importante, come non cadere in trappola con esse.

Strano risultato: null vs 0

Confrontiamo null con uno zero:

alert( null > 0 ); // (1) falsealert( null == 0 ); // (2) falsealert( null >= 0 ); // (3) true

Matematica, questo è strano. L’ultimo risultato afferma che “null è maggiore o uguale a zero”, quindi in uno dei confronti precedenti deve essere true, ma sono entrambi falsi.

La ragione è che un controllo di uguaglianza == e i confronti > < >= <= funzionano in modo diverso. I confronti convertono null in un numero, trattandolo come 0. Ecco perché (3) null >= 0 è vero e (1) null > 0 è falso.

D’altra parte, il controllo di uguaglianza == per undefined e null è definito in modo tale che, senza alcuna conversione, sono uguali tra loro e non sono uguali a nient’altro. Ecco perché (2) null == 0 è falso.

Un indefinito incomparabile

Il valore undefined non dovrebbe essere paragonato ad altri valori:

alert( undefined > 0 ); // false (1)alert( undefined < 0 ); // false (2)alert( undefined == 0 ); // false (3)

Perché lo zero non piace così tanto? Sempre falso!

Abbiamo questi risultati perché:

  • I confronti (1) e (2) restituiscono false perché undefined viene convertito in NaN e NaN è un valore numerico speciale che restituisce false per tutti i confronti.
  • Il controllo di uguaglianza (3) restituisce false perché undefined è uguale solo a null, undefined, e nessun altro valore.

Evitare problemi

Perché abbiamo esaminato questi esempi? Dovremmo ricordarci sempre di queste particolarità? Beh, non proprio. In realtà, queste cose complicate diventeranno gradualmente familiari con il tempo, ma c’è un modo solido per evitare problemi con esse:

  • Trattare qualsiasi confronto con undefined/null eccetto l’uguaglianza rigorosa === con cura eccezionale.
  • Non usare confronti >= > < <= con una variabile che può essere null/undefined, a meno che tu non sia veramente sicuro di quello che stai facendo. Se una variabile può avere questi valori, controllate separatamente.

Sommario

  • Gli operatori di confronto restituiscono un valore booleano.
  • Le stringhe sono confrontate lettera per lettera nell’ordine del “dizionario”.
  • Quando valori di tipo diverso sono confrontati, vengono convertiti in numeri (con l’esclusione di un controllo di uguaglianza rigoroso).
  • I valori null e undefined sono uguali == tra loro e non sono uguali a nessun altro valore.
  • Fate attenzione quando usate confronti come > o < con variabili che possono occasionalmente essere null/undefined. Controllare separatamente per null/undefined è una buona idea.

Similar Posts

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.