Quale operatore uguale (== vs ===) dovrebbe essere usato nei confronti di JavaScript?


5665

Sto usando JSLint per passare attraverso JavaScript, e sta restituendo molti suggerimenti per sostituire ==(due segni di uguale) con ===(tre segni di uguale) quando si fanno cose come il confronto idSele_UNVEHtype.value.length == 0all'interno di ifun'istruzione.

C'è un vantaggio prestazionale da sostituire ==con ===?

Qualsiasi miglioramento delle prestazioni sarebbe gradito dal momento che esistono molti operatori di confronto.

Se non si verifica alcuna conversione di tipo, si otterrebbe un miglioramento delle prestazioni ==?


134
A chi potrebbe essere interessato al medesimo soggetto === vs ==, ma in PHP, può leggere qui: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/...
Marco Demaio

257
Nel caso in cui qualcuno si chiedesse nel 2012: ===è molto più veloce di ==. jsperf.com/comparison-of-comparisons
Ry-

25
@minitech dovrebbe essere come non fa la conversione di tipo
Umur Kontacı

19
@minitech, dubito che qualcuno renderà la loro applicazione notevolmente più veloce usando ===over ==. In effetti, il benchmark non mostra una grande differenza tra entrambi sui browser moderni. Personalmente, di solito uso ==ovunque, a meno che non abbia davvero bisogno di una rigorosa uguaglianza.
laurent,

5
Ecco la parte del discorso di Crockford JS The Good Parts in cui discute gli operatori ===e ==: youtube.com/… Se non funziona, è alle 15:20
davidhiggins il

Risposte:


6486

L'operatore di uguaglianza rigorosa ( ===) si comporta in modo identico all'operatore di uguaglianza astratta ( ==) tranne per il fatto che non viene eseguita alcuna conversione di tipo e i tipi devono essere uguali per essere considerati uguali.

Riferimento: Tutorial Javascript: Operatori di confronto

L' ==operatore confronterà per l'uguaglianza dopo aver effettuato le conversioni di tipo necessarie . L' ===operatore non eseguirà la conversione, quindi se due valori non sono dello stesso tipo, ===verrà semplicemente restituito false. Entrambi sono ugualmente veloci.

Per citare l'eccellente JavaScript di Douglas Crockford : The Good Parts ,

JavaScript ha due serie di operatori di uguaglianza: ===e !==, e i loro gemelli malvagi ==e !=. I buoni funzionano come ti aspetteresti. Se i due operandi sono dello stesso tipo e hanno lo stesso valore, ===produce truee !==produce false. I gemelli malvagi fanno la cosa giusta quando gli operandi sono dello stesso tipo, ma se sono di tipi diversi, cercano di forzare i valori. le regole con cui lo fanno sono complicate e non memorabili. Questi sono alcuni dei casi interessanti:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Tabella di confronto di uguaglianza

La mancanza di transitività è allarmante. Il mio consiglio è di non usare mai i gemelli malvagi. Invece, usa sempre ===e !==. Tutti i confronti appena mostrati producono falsecon l' ===operatore.


Aggiornare:

Un buon punto è stato sollevato da @Casebash nei commenti e nella risposta di @Phillipe Laybaert riguardo agli oggetti. Per gli oggetti e agire in modo coerente tra loro (tranne in un caso speciale).=====

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Il caso speciale è quando si confronta una primitiva con un oggetto che valuta la stessa primitiva, a causa del suo metodo toStringo valueOf. Ad esempio, si consideri il confronto tra una primitiva di stringa e un oggetto stringa creato usando il Stringcostruttore.

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Qui l' ==operatore sta verificando i valori dei due oggetti e sta ritornando true, ma ===sta vedendo che non sono dello stesso tipo e ritornano false. Quale è corretto? Dipende davvero da cosa stai cercando di confrontare. Il mio consiglio è di bypassare completamente la domanda e semplicemente non usare il Stringcostruttore per creare oggetti stringa da valori letterali stringa.

Riferimento
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


237
=== non è più veloce se i tipi sono uguali. Se i tipi non sono uguali, === sarà più veloce perché non tenterà di eseguire la conversione.
Bill the Lizard,

521
=== non sarà mai più lento di ==. Entrambi eseguono il controllo del tipo, quindi === non fa nulla in più rispetto a ==, ma il controllo del tipo può consentire a === di uscire prima quando i tipi non sono uguali.
Bill the Lizard,

246
Sostituendo tutto == /! = Con === /! == aumenta la dimensione del file js, ci vorrà più tempo per caricare. :)
Marco Demaio

92
"... le regole con cui lo fanno sono complicate e non memorabili ..." Ora tali dichiarazioni ti fanno sentire così al sicuro durante la programmazione ...
Johan

47
Da Crockford: "La mancanza di transitività è allarmante". Se sviluppi software e non trovi la mancanza di transitività in un operatore di confronto allarmante, o se il confronto della velocità tra == e === o la dimensione del file / il tempo di caricamento hanno la precedenza nella tua mente sul determinismo transitivo del comportamento di un operatore di confronto, tu potrebbe essere necessario tornare indietro e ricominciare da capo.
jinglesthula,

1144

Utilizzo ==dell'operatore ( Uguaglianza )

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Utilizzo ===dell'operatore ( Identità )

true === 1; //false
"2" === 2;  //false

Questo perché l' operatore di uguaglianza ==digita la coercizione , nel senso che l'interprete tenta implicitamente di convertire i valori prima del confronto.

D'altra parte, l' operatore di identità ===non esegue la coercizione del tipo e quindi non converte i valori durante il confronto ed è quindi più veloce (come in base a questo test benchmark JS ) mentre salta di un passo.


9
@Software Monkey: non per tipi di valore (numero, booleano, ...)
Philippe Leybaert,

34
Poiché nessuno ha menzionato la tabella di uguaglianza di Javascript, eccola qui: dorey.github.io/JavaScript-Equality-Table
blaze

6
Nella prima affermazione, sei sicuro che 'true' sia convertito in 1 e non 1 in true?
Shadi Namrouti,

2
Da dove vengono i termini "uguaglianza" e "identità"? Lo standard non usa questi termini. Chiama =="uguaglianza astratta" e chiama ==="uguaglianza rigorosa". Concedere chiamando ==qualsiasi tipo di "uguaglianza" è terribile IMHO, dal momento che non è transitivo, ma perché cavillo? Prendo più problemi con "identità" però; Penso che quel termine sia piuttosto fuorviante, sebbene "funzioni". Ma seriamente, chi ha coniato il termine "identità"? Cerco lo standard e non sono riuscito a trovarlo.
Ray Toal,

1
"Identità" è decisamente la parola sbagliata. Confronti di identità in tutte le lingue che ho usato significa uno nello stesso oggetto , cioè le due variabili di riferimento indicano non solo entità equivalenti, ma la stessa entità.
Inigo,

724

Un'interessante rappresentazione pittorica del confronto di uguaglianza tra ==e ===.

Fonte: http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

Quando si utilizza ===per il test dell'uguaglianza JavaScript, tutto è come è. Nulla viene convertito prima di essere valutato.

Valutazione dell'uguaglianza di === in JS


var1 == var2

Quando si utilizza ==per il test dell'uguaglianza JavaScript, si verificano alcune conversioni funky.

Valutazione dell'uguaglianza di == in JS

Morale della storia:

Utilizzare a ===meno che non si comprenda appieno le conversioni che avvengono ==.


3
@mfeine intendi === o! == invece di == o! =. Non voglio confondere i nuovi programmatori;)
katalin_2003,

2
dalla mia esperienza nell'uso di tre uguali può causare problemi e dovrebbe essere evitato se non compreso appieno. due uguali produce risultati molto migliori perché il 99% delle volte non voglio che i tipi siano uguali.
vsync,

13
@vsync: se davvero non vuoi che i tipi siano uguali , dovresti usare tre uguali !
SNag

7
L'unica eccezione: puoi tranquillamente usare x == nullper verificare se xè nullo undefined.
Andy,

1
@ user648026: La domanda riguarda l'uguaglianza confronto con ==vs ===. Le maiuscole e le minuscole non sono uguali e torneranno falsecon entrambi ==e gli ===operatori. Inoltre, le parole chiave true, false, undefined, null, Infinityesistono JS solo in un caso, e non possono essere utilizzati nei casi superiori o misti.
SNag

609

Nelle risposte qui, non ho letto nulla su ciò che significa uguale . Alcuni diranno che ===significa uguale e dello stesso tipo , ma non è proprio vero. In realtà significa che entrambi gli operandi fanno riferimento allo stesso oggetto o, nel caso di tipi di valore, hanno lo stesso valore .

Quindi, prendiamo il seguente codice:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Lo stesso qui:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

O anche:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Questo comportamento non è sempre evidente. C'è di più nella storia che essere uguali ed essere dello stesso tipo.

La regola è:

Per i tipi di valore (numeri):
a === b restituisce vero seaebha lo stesso valore e sono dello stesso tipo

Per i tipi di riferimento:
a === b restituisce vero seae fabriferimento allo stesso oggetto esatto

Per le stringhe:
a === b restituisce vero seaebsono entrambe le stringhe e contengono esattamente gli stessi caratteri


Corde: il caso speciale ...

Le stringhe non sono tipi di valore, ma in Javascript si comportano come tipi di valore, quindi saranno "uguali" quando i caratteri nella stringa sono uguali e quando hanno la stessa lunghezza (come spiegato nella terza regola)

Ora diventa interessante:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Ma che ne dici di questo ?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Pensavo che le stringhe si comportassero come tipi di valore? Bene, dipende da chi chiedi ... In questo caso aeb non sono dello stesso tipo. aè di tipo Object, mentre bè di tipo string. Ricorda solo che la creazione di un oggetto stringa utilizzando il Stringcostruttore crea qualcosa di tipo Objectche si comporta come una stringa il più delle volte .


6
activa: Vorrei chiarire che le stringhe sono così uguali solo quando sono letterali. new String ("abc") === "abc" è falso (secondo la mia ricerca).
Lawrence Dol,

3
new Number() == "0". Anche in Firefox:(function(){}) == "function () {\n}"
Thomas Eding il

3
Grazie per aver spiegato il perché new String("123") !== "123". Sono di diversi tipi. Semplice ma confuso.
Styfle,

21
Stringgli oggetti si comportano come stringhe come qualsiasi altro oggetto . new Stringnon dovrebbe mai essere usato, in quanto ciò non crea stringhe reali. Una stringa reale e può essere creata con letterali stringa o chiamata Stringcome funzione senza new , ad esempio:String(0); //"0", Real string, not an object
Esailija

6
Ma nei casi dettagliati, l'operatore "==" si comporta esattamente allo stesso modo.
Yaron Levi,

270

Vorrei aggiungere questo consiglio:

In caso di dubbi, leggere le specifiche !

ECMA-262 è la specifica per un linguaggio di scripting di cui JavaScript è un dialetto. Ovviamente in pratica importa di più come si comportano i browser più importanti di una definizione esoterica di come dovrebbe essere gestita una cosa. Ma è utile capire perché la nuova stringa ("a")! == "a" .

Per favore, lasciami spiegare come leggere le specifiche per chiarire questa domanda. Vedo che in questo argomento molto antico nessuno ha avuto una risposta per l'effetto molto strano. Quindi, se riesci a leggere una specifica, questo ti aiuterà enormemente nella tua professione. È un'abilità acquisita. Quindi, continuiamo.

La ricerca nel file PDF di === mi porta a pagina 56 della specifica: 11.9.4. The Strict Equals Operator (===) , e dopo aver navigato attraverso le specifiche, trovo:

11.9.6 L'algoritmo di confronto sull'uguaglianza rigorosa
Il confronto x === y, dove xey sono valori, produce vero o falso . Tale confronto viene eseguito come segue:
  1. Se Tipo (x) è diverso da Tipo (y), restituisce false .
  2. Se Tipo (x) è Non definito, restituisce vero .
  3. Se Tipo (x) è Null, restituisce true .
  4. Se Tipo (x) non è Numero, andare al passaggio 11.
  5. Se x è NaN , restituire false .
  6. Se y è NaN , restituisce false .   8. Se x è +0 e y è −0, restituisce true .
  7. Se x ha lo stesso valore numerico di y, ritorna true .

  9. Se x è −0 e y è +0, restituisce true .
  10. Restituisci falso .
  11. Se Type (x) è String, restituisce true se xey sono esattamente la stessa sequenza di caratteri (stessa lunghezza e stessi caratteri nelle posizioni corrispondenti); altrimenti, restituisce false .
  12. Se Tipo (x) è Booleano, restituisce vero se xey sono entrambi veri o entrambi falsi ; in caso contrario, restituisce false .
  13. Restituisce verose xey si riferiscono allo stesso oggetto o se si riferiscono a oggetti uniti tra loro (vedere 13.1.2). Altrimenti, restituisci false .

Interessante è il passaggio 11. Sì, le stringhe vengono trattate come tipi di valore. Ma questo non spiega perché la nuova stringa ("a")! == "a" . Abbiamo un browser non conforme a ECMA-262?

Non così in fretta!

Controlliamo i tipi di operandi. Provalo tu stesso avvolgendoli in typeof () . Trovo che la nuova stringa ("a") sia un oggetto e viene utilizzato il passaggio 1: restituisce false se i tipi sono diversi.

Se ti chiedi perché la nuova stringa ("a") non restituisce una stringa, che ne dici di un esercizio che legge una specifica? Divertiti!


Aidiakapi ha scritto questo in un commento qui sotto:

Dalla specifica

11.2.2 Il nuovo operatore :

Se Type (costruttore) non è Object, genera un'eccezione TypeError.

In altre parole, se String non fosse di tipo Object, non potrebbe essere utilizzato con il nuovo operatore.

new restituisce sempre un oggetto, anche per i costruttori di stringhe . E ahimè! La semantica del valore per le stringhe (vedere il passaggio 11) viene persa.

E questo finalmente significa: new String ("a")! == "a" .


Il risultato del tipo (x) è implicito uguale al tipo di?
Dfr,

@nalply Non capisco esattamente l'ansia per il comportamento new String('x'), perché non ho mai visto alcun codice in natura che utilizza oggetti wrapper primitivi e non penso che ci siano molte buone ragioni per farlo, soprattutto al giorno d'oggi. Hai mai incontrato codice che lo fa?
Andy,

@Andy il problema è un codice di terze parti dannoso o sciatto, quindi non puoi presumere che nessuno lo usi new String().
nalply,

Se è sciatto, === è come lo scoprirai. Se è dannoso, penso che new String()sia probabilmente l'ultima delle tue preoccupazioni. Capisco la preoccupazione in teoria, ma hai ancora qualche esempio nel mondo reale? Per me è come la vecchia ansia che qualcuno potrebbe impostare undefinedsu un altro valore.
Andy,

Non so dove l'hai preso, ma il tuo algoritmo di confronto si sbaglia nel passaggio 2. La sezione "7.2.15 Confronto rigoroso sull'uguaglianza" controlla innanzitutto se i tipi sono uguali, se sì se sono Numero. In caso contrario, viene utilizzata la sezione "7.2.12 SameValueNonNumber (x, y)".
Rusty Core,

101

In PHP e JavaScript, è un rigoroso operatore di uguaglianza. Ciò significa che confronterà sia il tipo che i valori.


10
@ David: corretto. Ecco perché questa risposta è imprecisa (o addirittura sbagliata)
Philippe Leybaert,

7
@David var a = {}, b = {}; a == brestituisce false.
nyuszika7h,

6
Sì: due oggetti diversi con lo stesso tipo e valore confrontano false, ovvero questa risposta è sbagliata. Perché ha 50 voti positivi?
alexis,

4
Mi rendo conto che questo è vecchio, ma chiarire perché questa risposta è ancora "corretta" è perché nell'esempio var a = {}, b = {};Mentre entrambi aed bè effettivamente entrambi un oggetto, ma tecnicamente non hanno lo stesso valore. Sono casi diversi . Si noti che il confronto delle istanze si comporta in modo diverso rispetto al confronto delle primitive. Il che probabilmente aggiunge a questa confusione. Vedrai un comportamento di confronto simile se usi la versione di istanza di tipi di dati primitivi. Ad esempio new String('asdf')o new Number(5). Es: new Number(5) == new Number(5)è falso, anche se hanno lo stesso valore.
Norman Breau,

1
Tutti dimentichiamo che un riferimento a un oggetto è in realtà un tipo di valore, in quanto è un puntatore a uno slot di memoria. Il confronto degli oggetti non sta confrontando il "valore dell'oggetto" ma se entrambi i puntatori sono uguali, il che significa che fanno riferimento allo stesso slot di memoria. Questa è una differenza molto sottile nel confrontare i tipi, poiché l'operatore "===" deve davvero dire "se il tipo, il valore e il riferimento all'oggetto in memoria sono gli stessi".
Stokely,

101

Ho provato questo in Firefox con Firebug usando un codice come questo:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

e

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

I miei risultati (testati cinque volte ciascuno e mediati):

==: 115.2
===: 114.4

Quindi direi che la minuscola differenza (si tratta di oltre 100000 iterazioni, ricorda) è trascurabile. Prestazione non sono un motivo per farlo===. Digita sicurezza (beh, sicuro come stai per accedere a JavaScript), e la qualità del codice è.


3
Più che la sicurezza del tipo, vuoi la correttezza logica - a volte vuoi che le cose siano veritiere quando ==non sei d' accordo.
rpjohnst,

4
Ora, come si confrontano questi casi quando esiste un'effettiva coesione del tipo per l' ==operatore? Ricorda, è allora che c'è un aumento delle prestazioni.
Hubert OG,

2
PRINCIPALE differenza se testato correttamente per i motivi di cui sopra per verificare solo la disuguaglianza del tipo. jsfiddle.net/4jhuxkb2
Doug Morrow il

Misuri le prestazioni di qualcosa del genere in operazioni / secondo, non un singolo test in un singolo browser (uno con una quota di mercato del 5% circa) usando console.time () mentre usi un test che non accetta la coercizione del tipo (l'intero motivo è più lento) in considerazione. Questo è un test completamente insignificante. Lei ha ragione che le prestazioni non è la ragione per usare ===sopra ==, ma vi sbagliate che la loro performance è sostanzialmente uguali e che si potrebbe pensare questo test dimostra che, e che molte altre persone hanno deciso, è totalmente assurdo per me.
Stephen M Irving,

97

In JavaScript significa dello stesso valore e tipo.

Per esempio,

4 == "4" // will return true

ma

4 === "4" // will return false 

87

Il === operatore è chiamato un rigoroso operatore di confronto, si fa differire dal == operatore.

Consente di prendere 2 var a e b.

Affinché "a == b" valuti come vero aeb deve avere lo stesso valore .

Nel caso di "a === b" aeb devono avere lo stesso valore e anche lo stesso tipo per poter essere considerato vero.

Prendi il seguente esempio

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

In sintesi ; l'utilizzo dell'operatore == potrebbe valutare true in situazioni in cui non lo si desidera, quindi utilizzare === dell'operatore sarebbe più sicuro.

Nello scenario di utilizzo del 90% non importa quale si utilizza, ma è utile conoscere la differenza quando si verificano comportamenti imprevisti un giorno.


82

Perché ==è così imprevedibile?

Cosa ottieni quando confronti una stringa vuota ""con il numero zero 0?

true

Sì, è vero secondo == una stringa vuota e il numero zero è allo stesso tempo.

E non finisce qui, eccone un altro:

'0' == false // true

Le cose si fanno davvero strane con le matrici.

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

Quindi più strano con le stringhe

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

La situazione peggiora:

Quando è uguale non è uguale?

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

Lasciami dire ancora:

(A == B) && (B == C) // true
(A == C) // **FALSE**

E questa è solo la roba folle che ottieni con i primitivi.

È un livello completamente nuovo di folle quando si utilizza ==con gli oggetti.

A questo punto probabilmente ti stai chiedendo ...

Perché succede?

Bene, perché a differenza di "triple uguale" ( ===) che controlla solo se due valori sono uguali.

==fa un sacco di altre cose .

Ha una gestione speciale per le funzioni, una gestione speciale per null, indefinito, stringhe, lo chiami.

È piuttosto strano.

In effetti, se provassi a scrivere una funzione che fa quello ==che farebbe sarebbe simile a questo:

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);
    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

Che cosa significa questo?

Significa == è complicato.

Perché è complicato è difficile sapere cosa succederà quando lo si utilizza.

Ciò significa che potresti finire con dei bug.

Quindi la morale della storia è ...

Rendi la tua vita meno complicata.

Usa ===invece di ==.

Fine.


Hai looseEqualtorto. Function == Function.toString()è vero, ma looseEqual(Function, Function.toString())è falso. Non sono sicuro del motivo per cui si filtrano le funzioni all'inizio.
Oriol,

@Oriol avevi ragione, ho aggiornato il codice per tener conto di ciò, FYI sulla base dei miei test non era abbastanza per rimuovere il filtro per "funzioni", invece le "funzioni" dovevano essere gestite in modo diverso.
Luis Perez,

Ricorda che le specifiche non trattano le funzioni in modo diverso, sono solo oggetti. Il problema sembra fare affidamento typeof x === "object"per verificare se si tratta di un oggetto, ma `typeof funziona solo per primitive non nulle. Potresti essere interessato al mio elenco di modi adeguati per verificare se un valore è un oggetto
Oriol

Ho provato a trattare funzioni e oggetti allo stesso modo, ma ho scoperto che i risultati non erano corretti. Ad esempio, se le funzioni fossero trattate come oggetti, il confronto tra una funzione e un oggetto che implementa la funzione valueOf () o toString () che corrisponde alla funzione passerebbe, ma in realtà non lo è. Esempio: (function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}- dai un'occhiata a questo JS Fiddle che esegue tutti i test: jsfiddle.net/luisperezphd/7k6gcn6g (ci sono 1.225 permutazioni di test)
Luis Perez

1
Hai ragione, ottime osservazioni, questo sottolinea il punto principale che ==fa molte cose rendendo molto difficile anticipare i risultati mentre=== è molto più semplice e prevedibile, il che è uno dei motivi principali ===è la scelta raccomandata. (Aggiungerò una nota alla risposta che menziona il tuo punto)
Luis Perez,

81

===controlla che gli stessi lati siano uguali sia nel tipo che nel valore .


Esempio:

'1' === 1 // will return "false" because `string` is not a `number`

Esempio comune:

0 == ''  // will be "true", but it's very common to want this check to be "false"

Un altro esempio comune:

null == undefined // returns "true", but in most cases a distinction is necessary

Molte volte un controllo non tipizzato sarebbe utile perché non ti importa se il valore è uno dei dueundefined , null, 0 o""


7
inoltre,'string' !== 'number'
Omero il

72

Diagramma di flusso di esecuzione JavaScript per l'uguaglianza rigorosa / Confronto '==='

Javascript uguaglianza rigorosa

Diagramma di flusso di esecuzione Javascript per uguaglianza / confronto non rigorosi '=='

Javascript non uguaglianza


Non capisco perché la stringfreccia indica la grande scatola grigia, dovrebbe significare che l'interrutore sta lanciando la stringa su un numero?
vsync,

@vsync Indica l'opzione stringa all'interno della casella grigia, ovvero stringa -> # || NaN. Javascript non è un linguaggio di tipo script, in pratica può avere qualsiasi tipo di variabile. Quindi, è puntato su quella scatola grigia.
Samar Panda,

Ho semplicemente chiesto se è per scopi di casting dal momento che stringsi suppone che sia confrontato con un tipo number, quindi l'interrutore guarda a cosa la stringa dovrebbe essere confrontata e la lancia di conseguenza?
vsync,

1
La grande scatola grigia è ciò ToNumberche ritorna quando vengono dati tipi diversi, quindi se viene data una stringa sceglierà solo l'ultima opzione (e la convertirà in un numero). ==utilizza ToNumbersolo nei casi string == numbero boolean == anythingsopra (e solo su string/ boolean). Questo significa ==che non si convertirà mai undefinedo nullanche se sono nella casella grigia. (Per qualsiasi combinazione di uno undefinedo nullentrambi, ==verrà sempre restituito true. Inoltre, indipendentemente dal fatto che un valore si trovi sul lato sinistro o destro, ==(e ===) restituirà lo stesso risultato.)
user2033427

55

JavaScript === vs == .

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type

54

Significa uguaglianza senza tipo coercizione tipo coercizione significa che JavaScript non converte automaticamente nessun altro tipo di dati in tipi di dati stringa

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 

48

In uno script tipico non ci saranno differenze di prestazioni. Più importante potrebbe essere il fatto che mille "===" sono 1 KB più pesanti di mille "==" :) Profilatori JavaScript possono dirti se c'è una differenza di prestazioni nel tuo caso.

Ma personalmente farei ciò che JSLint suggerisce. Questa raccomandazione non è presente a causa di problemi di prestazioni, ma perché il tipo coercizione significa ('\t\r\n' == 0)vero.


4
Non sempre vero Con la compressione gzip, la differenza sarebbe quasi trascurabile.
Daniel X Moore,

1
D'accordo, ma migliaia "===" significa anche 10 migliaia di righe di codice, quindi 1kb più o meno ...;)
Jonny,

Se sei preoccupato per le dimensioni, quindi scambia tutte le tue == con ===, quindi usa una regexp racchiusa in una

46

L'operatore di confronto uguale == è confuso e dovrebbe essere evitato.

Se DEVI convivere con esso, ricorda le seguenti 3 cose:

  1. Non è transitivo: (a == b) e (b == c) non portano a (a == c)
  2. Si esclude a vicenda con la sua negazione: (a == b) e (a! = B) mantengono sempre valori booleani opposti, con tutti a e b.
  3. In caso di dubbio, apprendi a memoria la seguente tabella di verità:

TABELLA DI VERITÀ PER GLI OPERATORI PARI IN JAVASCRIPT

  • Ogni riga nella tabella è un insieme di 3 valori reciprocamente "uguali", il che significa che ogni 2 valori tra loro sono uguali usando il segno uguale == *

** STRANGE: nota che due valori sulla prima colonna non sono uguali in questo senso. **

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.

39

È improbabile che ci sia una differenza di prestazioni tra le due operazioni durante l'utilizzo. Non è necessario eseguire alcuna conversione di tipo perché entrambi i parametri sono già dello stesso tipo. Entrambe le operazioni avranno un confronto del tipo seguito da un confronto del valore.


38

Sì! Importa.

===l'operatore in javascript controlla il valore e digita dove l' ==operatore controlla il valore (digita la conversione se necessario) .

inserisci qui la descrizione dell'immagine

Puoi facilmente provarlo. Incolla il seguente codice in un file HTML e aprilo nel browser

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

Riceverai " falso " in allerta. Ora modifica il onPageLoad()metodo per alert(x == 5);te diventerà vero .


33

=== l'operatore controlla i valori e i tipi di variabili per l'uguaglianza.

== l'operatore controlla semplicemente il valore delle variabili per l'uguaglianza.


32

È un test di controllo rigoroso.

È una buona cosa soprattutto se stai controllando tra 0 e false e null.

Ad esempio, se hai:

$a = 0;

Poi:

$a==0; 
$a==NULL;
$a==false;

Tutto ritorna vero e potresti non volerlo. Supponiamo che tu abbia una funzione che può restituire il nono indice di un array o falso in caso di fallimento. Se si seleziona "==" false, è possibile ottenere un risultato confuso.

Quindi, con la stessa cosa di cui sopra, ma un test rigoroso:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false

3
In JavaScript, questo è completamente sbagliato e erroneamente incompleto. 0 != null. -1
Ry-

31

A volte JSLint ti dà ragioni irrealistiche per modificare le cose. ===ha esattamente le stesse prestazioni di== se i tipi sono già gli stessi.

È più veloce solo quando i tipi non sono gli stessi, nel qual caso non tenta di convertire i tipi ma restituisce direttamente un falso.

Quindi, IMHO, JSLint forse scrivevano nuovo codice, ma inutili ottimizzazioni eccessive dovrebbero essere evitate a tutti i costi.

Significato, non v'è alcun motivo di cambiare ==ad ===un assegno comeif (a == 'test') quando si sa che per un fatto che una può essere solo una stringa.

Modificare un sacco di codice in questo modo fa perdere tempo agli sviluppatori e ai revisori e non ottiene nulla.


30

Semplicemente

==significa confronto tra operandi con type conversion

&

===significa confronto tra operandi senza type conversion

La conversione del tipo in javaScript significa che javaScript converte automaticamente qualsiasi altro tipo di dati in tipi di dati stringa.

Per esempio:

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 

26

Un semplice esempio è

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.

25

Le prime 2 risposte sono entrambe menzionate == significa uguaglianza e === significa identità. Sfortunatamente, questa affermazione non è corretta.

Se entrambi gli operandi di == sono oggetti, vengono confrontati per vedere se sono lo stesso oggetto. Se entrambi gli operandi puntano allo stesso oggetto, l'operatore uguale restituisce true. Altrimenti, i due non sono uguali.

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

Nel codice sopra, sia == che === diventano falsi perché aeb non sono gli stessi oggetti.

Vale a dire: se entrambi gli operandi di == sono oggetti, == si comporta come ===, che significa anche identità. La differenza essenziale di questi due operatori riguarda la conversione dei tipi. == ha una conversione prima di controllare l'uguaglianza, ma === no.


24

Come regola generale, generalmente userei ===invece di ==(e !==invece di!= ).

Le ragioni sono spiegate nelle risposte sopra e anche Douglas Crockford ne è abbastanza chiaro ( JavaScript: le parti buone ).

Tuttavia, esiste una sola eccezione : == nullè un modo efficace per verificare "è nullo o non definito":

if( value == null ){
    // value is either null or undefined
}

Ad esempio jQuery 1.9.1 utilizza questo modello 43 volte e il correttore di sintassi JSHint fornisce anche ileqnull opzione rilassante per questo motivo.

Dalla guida di stile jQuery :

Controlli rigorosi sull'uguaglianza (===) dovrebbero essere usati a favore di ==. L'unica eccezione riguarda il controllo di undefined e null mediante null.

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

22

Il problema è che potresti facilmente metterti nei guai poiché JavaScript ha molte conversioni implicite che significano ...

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

Che abbastanza presto diventa un problema. Il miglior esempio del perché la conversione implicita è "malvagio" può essere preso da questo codice in MFC / C ++ che in realtà verrà compilato a causa di una conversione implicita da CString a HANDLE che è un tipo di puntatore tipedef ...

CString x;
delete x;

Che ovviamente durante il runtime fa cose molto indefinite ...

Google per conversioni implicite in C ++ e STL per ottenere alcuni degli argomenti contro di esso ...


2
0 == nullè falso.
Garrett,


21

Confronto di uguaglianza:

Operatore ==

Restituisce vero, quando entrambi gli operandi sono uguali. Gli operandi vengono convertiti nello stesso tipo prima di essere confrontati.

>>> 1 == 1
true
>>> 1 == 2
false
>>> 1 == '1'
true

Parità e confronto dei tipi:

Operatore ===

Restituisce vero se entrambi gli operandi sono uguali e dello stesso tipo. In genere è meglio e più sicuro se si confronta in questo modo, perché non ci sono conversioni di tipo dietro le quinte.

>>> 1 === '1'
false
>>> 1 === 1
true


20

null e indefinito sono il nulla, cioè

var a;
var b = null;

Qui ae bnon hanno valori. Considerando che 0, false e '' sono tutti valori. Una cosa comune tra tutti questi è che sono tutti valori falsi, il che significa che tutti soddisfano condizioni di falsità.

Quindi, 0, false e '' insieme formano un sottogruppo. E d'altra parte, null e indefinito formano il secondo sottogruppo. Controlla i confronti nell'immagine qui sotto. null e indefinito sarebbero uguali. Gli altri tre sarebbero uguali tra loro. Tuttavia, sono tutti trattati come condizioni di falsità in JavaScript.

Inserisci qui la descrizione dell'immagine

Questo è uguale a qualsiasi oggetto (come {}, array, ecc.), Stringa non vuota e valore booleano vero sono tutte condizioni veritiere. Ma non sono tutti uguali.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.