Menu

Operatori di uguaglianza in JavaScript: == vs === e Object.is

Come funziona l'uguaglianza in JavaScript: stretta e non stretta, le stranezze di ==, il comportamento di NaN e degli oggetti, e quando usare Object.is.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Due modi per chiedere "sono uguali?"

JavaScript ti dà due operatori di uguaglianza: === (stretto) e == (non stretto). Sembrano quasi identici. Si comportano in modo molto diverso.

=== controlla se entrambi gli operandi hanno lo stesso tipo e lo stesso valore. == prima converte gli operandi in un tipo comune, poi li confronta. È da questa conversione, la coercizione di tipo, che nasce gran parte della cattiva fama dell'uguaglianza in JavaScript.

La versione breve: usa === come scelta predefinita. La versione lunga vale la pena leggerla una volta, così sai a cosa stai rinunciando.

Uguaglianza stretta: probabilmente quello che vuoi

=== restituisce true solo quando entrambi i lati coincidono per tipo e valore. Nessuna conversione, nessuna sorpresa:

Se i tipi non coincidono, la risposta è subito false. Se coincidono, JavaScript confronta i valori. Per i primitivi è un confronto di valore; per gli oggetti è un confronto di riferimento (ci torniamo tra poco).

!== è l'operatore di disuguaglianza stretta e segue le stesse regole al contrario.

Uguaglianza non stretta: coercizione travestita

== permette che i due lati abbiano tipi diversi. Prima del confronto, esegue una serie di conversioni per cercare di farli coincidere:

Le regole esatte sono nella specifica, e non sono terribili, ma ricordarle nel mezzo di un debug è un'altra storia. Che "0" == false sia true sorprende anche gli sviluppatori esperti. Lo stesso vale per [] == false (anche questo true, perché l'array viene convertito in "", che viene convertito in 0).

Ecco perché la maggior parte delle guide di stile, e la regola eqeqeq di ESLint, ti dicono di usare === come scelta predefinita. Scambi un carattere in più da digitare con regole che riesci davvero a ricordare.

L'unico pattern utile con ==

C'è un solo idioma con l'uguaglianza non stretta che vale la pena conoscere: x == null restituisce true quando x è null oppure undefined, e false per tutto il resto.

L'equivalente stretto è x === null || x === undefined, che funziona ma si legge peggio. Molte codebase ammettono == null come unica eccezione consentita. Scegli una regola e applicala con coerenza.

Gli oggetti si confrontano per riferimento

Per oggetti, array e funzioni, sia === sia == si pongono la stessa domanda: "entrambi i lati puntano allo stesso oggetto in memoria?". Non "hanno lo stesso contenuto?".

Due oggetti letterali con contenuto identico restano due oggetti diversi. Prima o poi ci cascano tutti.

Per un confronto basato sui valori scrivi una tua funzione di supporto, usi una libreria (lodash.isequal) o serializzi con JSON.stringify nel caso di semplici oggetti piatti:

JSON.stringify funziona solo con dati semplici: ignora funzioni, undefined e symbol, e non garantisce l'ordine delle chiavi tra motori diversi per tutte le forme. È un controllo rapido, non una soluzione generale.

NaN non è uguale a niente

NaN ("not a number") è il valore che JavaScript restituisce quando un'operazione numerica non ha una risposta sensata: 0/0, Number("abc"), Math.sqrt(-1). Entrambi gli operatori di uguaglianza restituiscono false quando uno dei due lati è NaN, anche quando lo sono entrambi:

Per rilevare NaN, usa Number.isNaN(value). Non usare la vecchia funzione globale isNaN: converte prima il suo argomento, quindi isNaN("hello") restituisce true, cosa che non è quasi mai quello che vuoi.

Object.is: quasi ===, con due correzioni

Object.is(a, b) si comporta come === tranne che in due casi limite:

Quasi sempre quello che vuoi è ===. Usa Object.is quando ti serve specificamente trattare NaN come uguale a sé stesso, o distinguere +0 da -0: entrambi casi rari, ma a volte importanti nel codice numerico e negli interni dei framework (React usa Object.is per confrontare lo stato).

Gli operatori di disuguaglianza seguono la stessa divisione

!== è stretto, != non è stretto, e vale lo stesso consiglio:

Usa !== come scelta predefinita. Se hai già ammesso == null, puoi ammettere anche il suo opposto != null per il controllo "né null né undefined".

Una checklist per i confronti

Quando devi confrontare due valori, segui questi passaggi:

  • Primitivi, con lo stesso tipo atteso? Usa ===.
  • Controlli null o undefined? x == null va bene se la tua guida di stile lo permette; altrimenti x === null || x === undefined.
  • Controlli NaN? Number.isNaN(x).
  • Confronti oggetti per identità? === fa esattamente quello che vuoi.
  • Confronti oggetti per contenuto? Scrivi una funzione di supporto, usa una libreria o serializza. Gli operatori integrati non possono aiutarti.

Resta su ===, considera == uno strumento speciale per il caso == null, ed eviterai le stranezze dell'uguaglianza che riempiono le FAQ su JavaScript.

Prossimo passo: gli operatori

L'uguaglianza è solo una parte degli operatori di JavaScript. La prossima pagina passa in rassegna tutti gli altri: aritmetici, logici, di assegnazione e gli operatori abbreviati su cui farai affidamento nel codice di tutti i giorni.

Domande frequenti

Che differenza c'è tra == e === in JavaScript?

=== è l'uguaglianza stretta: restituisce true solo se entrambi gli operandi hanno lo stesso tipo e lo stesso valore. == è l'uguaglianza non stretta: converte gli operandi nello stesso tipo prima di confrontarli. 1 === '1' è false, ma 1 == '1' è true perché == converte prima la stringa in numero.

Devo usare sempre === in JavaScript?

Come scelta predefinita, sì. === è prevedibile e le sue regole si ricordano facilmente. L'eccezione più comune è x == null, che comodamente corrisponde sia a null sia a undefined. La maggior parte dei linter (la regola eqeqeq di ESLint) impone === e permette quel pattern come eccezione facoltativa.

Perché NaN === NaN restituisce false?

Lo standard IEEE 754 stabilisce che NaN non è uguale a niente, nemmeno a sé stesso. Per questo ogni operatore di uguaglianza restituisce false quando c'è di mezzo NaN. Usa Number.isNaN(x) per controllare se un valore è NaN, oppure Object.is(NaN, NaN), che restituisce true.

Come confronto due oggetti in JavaScript?

Sia == sia === confrontano gli oggetti per riferimento, non per contenuto. {a: 1} === {a: 1} è false perché sono oggetti diversi. Per confrontarli per valore devi scrivere un controllo tuo, usare una libreria come isEqual di Lodash, oppure serializzarli con JSON.stringify se sono semplici oggetti piatti.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA