Domanda Quale operatore uguale (== vs ===) dovrebbe essere utilizzato nei confronti JavaScript?


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

C'è un vantaggio in termini di prestazioni per la sostituzione == con ===?

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

Se non avviene alcuna conversione del tipo, si otterrebbe un aumento delle prestazioni ==?


5674
2017-12-11 14:19


origine


risposte:


L'identità ( ===) l'operatore si comporta in modo identico all'uguaglianza ( ==operatore) tranne che per la conversione del tipo non eseguita e i tipi devono essere uguali per essere considerati uguali.

Riferimento: Esercitazione Javascript: Operatori di confronto

Il == l'operatore si confronterà per l'uguaglianza dopo aver effettuato tutte le conversioni di tipo necessarie . Il === l'operatore lo farà non  fai la conversione, quindi se due valori non sono dello stesso tipo === semplicemente tornerà false. Entrambi sono ugualmente veloci.

Per citare l'eccellente di Douglas Crockford JavaScript: Le buone parti ,

JavaScript ha due gruppi di operatori di uguaglianza: === e !==e i loro gemelli malvagi == e !=. I bravi funzionano come ti aspetteresti. Se i due operandi sono dello stesso tipo e hanno lo stesso valore, allora === produce true e !== produce false. I gemelli malvagi fanno la cosa giusta quando gli operandi sono dello stesso tipo, ma se sono di tipi diversi, tentano di forzare i valori. le regole con cui lo fanno sono complicate e non memorizzabili. 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

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 false con il === operatore.


Aggiornare:

Un buon punto è stato sollevato da @Casebash  nei commenti e in @Phillipe Laybaert's   risposta  riguardante i tipi di riferimento. Per i tipi di riferimento == e === agire coerentemente l'uno con l'altro (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 un valore letterale con un oggetto che valuta lo stesso valore letterale, a causa del suo valore toString o valueOf metodo. Ad esempio, si consideri il confronto di un letterale stringa con un oggetto stringa creato dal String costruttore.

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

Qui il == l'operatore sta controllando i valori dei due oggetti e ritornando true, ma il === sta vedendo che non sono dello stesso tipo e stanno tornando false. Quale è corretto? Dipende molto da cosa stai cercando di confrontare. Il mio consiglio è di ignorare completamente la domanda e semplicemente non usare il String costruttore per creare oggetti stringa.

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


5715
2017-12-11 14:25



Usando il ==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

Usando il ===operatore ( Identità )

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

Questo perché il operatore di uguaglianza == fa tipo coercizione , il che significa che l'interprete cerca implicitamente di convertire i valori prima di confrontarli.

D'altra parte, il operatore di identità === non fa tipo di coercizione , e quindi non converte i valori durante il confronto.


988
2018-06-05 19:11



Nelle risposte qui, non ho letto nulla su cosa pari  si intende. Alcuni lo diranno === si intende uguale e dello stesso tipo , ma non è proprio vero. In realtà significa questo entrambi gli operandi fanno riferimento allo stesso oggetto o in 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 ovvio. 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 se a e b hanno lo stesso valore e sono dello stesso tipo

Per i tipi di riferimento:
a === b restituisce vero se a e b fare riferimento allo stesso identico oggetto

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


Archi: 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? Beh, dipende da chi chiedi ... In questo caso a e b non sono dello stesso tipo. a è di tipo Object, mentre b è di tipo string. Basta ricordare che creare un oggetto stringa usando il String costruttore crea qualcosa di tipo Object che si comporta come una stringa La maggior parte delle volte .


545
2018-05-05 05:21



Una rappresentazione pittorica interessante del confronto di uguaglianza tra == e ===.

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


var1 === var2

Quando si usa === per il test di uguaglianza di JavaScript, tutto è così com'è. Nulla viene convertito prima di essere valutato.

Equality evaluation of === in JS


var1 == var2

Quando si usa == per il test di uguaglianza JavaScript, alcuni   le conversioni funky hanno luogo.

Equality evaluation of == in JS

Morale della storia:  

Uso === a meno che tu non comprenda pienamente il   conversioni che avvengono con ==.


519
2017-11-28 18:18



Lasciatemi aggiungere questo consiglio:

In caso di dubbio, leggi il specificazione !  

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

Per favore lasciami spiegare come leggere le specifiche per chiarire questa domanda. Vedo che in questo argomento molto vecchio nessuno aveva una risposta per lo strano effetto. Quindi, se puoi leggere una specifica, questo ti aiuterà moltissimo nella tua professione. È un'abilità acquisita. Quindi, continuiamo.

La ricerca del file PDF per === mi porta alla pagina 56 della specifica: 11.9.4. The Strict Equals Operator (===) e dopo aver attraversato il specificationalese trovo:

11.9.6 Algoritmo di confronto rigoroso di uguaglianza
  Il confronto x === y, dove xey sono valori, produce vero  o falso . Tale confronto viene eseguito come segue:
  1. Se Type (x) è diverso da Type (y), return falso .
  2. Se Type (x) è Undefined, return vero .
  3. Se Type (x) è Null, return vero .
  4. Se Type (x) non è Number, andare al passaggio 11.
  5. Se x è NaN , ritorno falso .
  6. Se lo è NaN , ritorno falso .
  7. Se x è lo stesso valore numerico di y, return vero .
  8. Se x è +0 e y è -0, ritorna vero .
  9. Se x è -0 e y è +0, ritorna vero .
  10. Ritorno falso .
  11. Se Type (x) è String, quindi restituire vero  se x e y sono esattamente la stessa sequenza di caratteri (stessa lunghezza e stessi caratteri nelle posizioni corrispondenti); altrimenti, ritorno falso .
  12. Se Type (x) è booleano, restituisci vero  se x e y sono entrambi vero  o entrambi falso ; altrimenti, ritorno falso .
  13. Ritorno vero  se x e y si riferiscono allo stesso oggetto o se si riferiscono ad oggetti uniti tra loro (vedi 13.1.2). Altrimenti, ritorno falso .

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

Non così in fretta!

Controlliamo i tipi di operandi. Provalo tu stesso avvolgendolo tipo di() . trovo che nuova stringa ("a")  è un oggetto e viene utilizzato il passaggio 1: return falso  se i tipi sono diversi

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


Aidiakapi ha scritto questo in un commento qui sotto:

Dalle specifiche

11.2.2 Il nuovo operatore :

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

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

nuovo  restituisce sempre un oggetto, anche per Stringa  costruttori, anche. E ahimè! La semantica del valore per le stringhe (vedere il punto 11) viene persa.

E questo significa finalmente: nuova stringa ("a")! == "a" .


250
2018-05-12 12:58



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


93
2017-12-25 11:17



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 una media):

==: 115.2
===: 114.4

Quindi direi che la differenza minuscola (questo è più di 100000 iterazioni, ricorda) è trascurabile. Prestazione non è  una ragione per fare ===. Digita la sicurezza (beh, così sicuro come stai per ottenere in JavaScript), e la qualità del codice è.


88
2018-05-12 12:58