Object.is vs ===


141

Mi sono imbattuto in un esempio di codice che utilizzava questo confronto:

var someVar = 0;
Object.is(false, someVar); //Returns false 

So false == 0che sarà trueper questo che abbiamo ===.

Quanto è Object.isdiverso da ===?

Risposte:


174

===viene chiamato operatore di confronto rigoroso in JavaScript. Object.ise l'operatore di confronto rigoroso si comporta esattamente lo stesso tranne per NaNe +0/-0.

Da MDN:

Object.is()il metodo non equivale a essere uguale secondo l' ===operatore. L' ===operatore (e anche l' ==operatore) tratta i valori numerici -0 e +0 come uguali e tratta Number.NaNcome non uguali NaN.

Il codice seguente evidenzia la differenza tra ===e Object.is().

console.log(+0 === -0); //true
console.log(Object.is(+0, -0)); //false

console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); //true

console.log(Number.NaN === Number.NaN); // false
console.log(Object.is(Number.NaN, Number.NaN)); // true

console.log(NaN === Number.NaN); // false
console.log(Object.is(NaN, Number.NaN)); // true

inserisci qui la descrizione dell'immagine

Puoi trovare altri esempi qui .

Nota : Object.isfa parte della proposta ECMAScript 6 e non è ancora ampiamente supportato (ad es. Non è supportato da nessuna versione di Internet Explorer o da molte versioni precedenti di altri browser). Tuttavia, è possibile utilizzare un polyfill per browser non ES6 che è possibile trovare nel collegamento indicato sopra.


26
La prima riga della risposta dovrebbe essere "Si comportano esattamente allo stesso modo tranne per NaN e +0 e -0", probabilmente.
Benjamin Gruenbaum,

1
@BenjaminGruenbaum Buon suggerimento. Rende la risposta più facile da leggere. Saluti.
Gurpreet Singh,

3
@ humble.rumble questo è stato discusso a lungo - i metodi statici sono più semplici - non hanno problemi di contesto o problemi primitivi. Ad esempio, nel tuo esempio mi aspetterei false, ma i principianti di JS si aspetterebbero true dal momento che fare .xsu una stringa lo racchiude in un Stringoggetto (e non un valore primitivo di stringa) e il confronto sarebbe tra un oggetto e una stringa - questo è molto sottile ed è una trappola - la statica evita questi problemi, i metodi statici sono più semplici e più facili da usare.
Benjamin Gruenbaum,

2
@ humble.rumble Per confrontare i nodi DOM, esiste già un tale metodo, vedere isEqualNode . Esempio:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W,

2
Aggiornamento 2017: Object.is () è ora ampiamente supportato in tutti i principali browser.
Sterling Bourne,

56

Object.isutilizza l' algoritmo SameValue della specifica , mentre ===utilizza l' algoritmo di uguaglianza rigorosa . Una nota sull'algoritmo di uguaglianza rigorosa evidenzia la differenza:

Questo algoritmo differisce dall'algoritmo SameValue ... nel suo trattamento di zero e NaN firmati.

Nota che:

  • NaN === NaN è falso, ma Object.is(NaN, NaN) è vero
  • +0 === -0 è vero, ma Object.is(+0, -0)è falso
  • -0 === +0è vero, ma Object.is(-0, +0)è falso

JavaScript ha almeno quattro tipi di "uguaglianza":

  • "Loose" ( ==), dove gli operandi saranno costretti a cercare di farli combaciare. Le regole sono chiaramente specificate , ma non ovvie. ( "" == 0è true; "true" == trueèfalse , ...).
  • "Strict" ( ===), in cui gli operandi di tipi diversi non saranno forzati (e non saranno uguali), ma vedi la nota sopra circaNaN e zero positivo e negativo.
  • SameValue - come elencato sopra (usato da Object.is ).
  • SameValueZero - like SameValuetranne +0e -0sono uguali anziché diversi (usato da Mapper i tasti e da Array.prototype.includes).

C'è anche l' equivalenza degli oggetti , che non è fornita dal linguaggio o dal runtime stesso, ma di solito è espressa come: Gli oggetti hanno lo stesso prototipo, le stesse proprietà e i loro valori di proprietà sono gli stessi (secondo una ragionevole definizione di "lo stesso" ).


Algoritmo SameValue :

  • Se Tipo (x) è diverso da Tipo (y), restituisce false.
  • Se Tipo (x) è Numero, allora
    • Se x è NaN e y è NaN, restituisce true.
    • Se x è +0 e y è -0, restituisce false.
    • Se x è -0 e y è +0, restituisce false.
    • Se x ha lo stesso valore numerico di y, restituisce true.
    • Restituisci falso.
  • Restituisce SameValueNonNumber (x, y).

... dove SameValueNonNumber è:

  • Assert: Type (x) non è Number.
  • Assert: Type (x) è uguale a Type (y).
  • Se Tipo (x) è Non definito, restituisce vero.
  • Se Tipo (x) è Null, restituisce true.
  • Se Tipo (x) è String, allora
    • Se xey sono esattamente la stessa sequenza di unità di codice (stessa lunghezza e stesse unità di codice negli indici corrispondenti), restituisce true; altrimenti, restituisce false.
  • Se Tipo (x) è Booleano, allora
    • Se xey sono entrambi veri o entrambi falsi, restituisce vero; altrimenti, restituisce false.
  • Se Tipo (x) è Simbolo, allora
    • Se xey hanno entrambi lo stesso valore del simbolo, restituisce true; altrimenti, restituisce false.
  • Restituisce vero se xey hanno lo stesso valore Oggetto. Altrimenti, restituisci false.

Algoritmo di uguaglianza rigorosa :

  1. Se Tipo (x) è diverso da Tipo (y), restituisce false.
  2. Se Tipo (x) è Numero, allora
    • Se x è NaN, restituisce false.
    • Se y è NaN, restituisce false.
    • Se x ha lo stesso valore numerico di y, restituisce true.
    • Se x è +0 e y è -0, restituisce true.
    • Se x è -0 e y è +0, restituisce true.
    • Restituisci falso.
  3. Restituisce SameValueNonNumber (x, y).

2

Object.is = function(v1, v2){
  //test for `-0`
  if(v1 === 0 && v2 === 0) {
    return 1 / v1 === 1 / v2;
  }
  
  //test for `NaN`
  if(v1 !== v1) {
    return v2 !== v2;
  }
  
  //everything else
  return v1 === v2;
}

Quanto sopra è la funzione polyfill per mostrare come Object.isfunziona, per chiunque sia interessato a saperlo. Un riferimento a You-Don't-Know-JS


2

Sommario:

La Object.is()funzione accetta 2 valori come argomenti e restituisce true se i 2 valori indicati sono identici, altrimenti restituirà false.

perché ne abbiamo bisogno?

Potresti pensare che abbiamo già un controllo di uguaglianza rigorosa (tipo di controllo + valore) in javascript con l' ===operatore, perché abbiamo bisogno di questa funzione? Bene l'uguaglianza rigorosa non è sufficiente in alcuni casi e sono i seguenti:

console.log(NaN === NaN);   // false
console.log(-0 === +0);     // true

Object.is() ci aiuta a essere in grado di confrontare questi valori per vedere se sono simili, cosa che il rigoroso operatore per la parità non può fare.

console.log(Object.is(NaN, NaN));  // true
console.log(Object.is(-0, 0));     // false
console.log(Object.is(+0, +0));    // true
console.log(Object.is(+0, -0));    // false


0

In breve, sono simili, ma Object.issono più intelligenti e più accurati ...

Diamo un'occhiata a questo ...

+0 === -0 //true

Ma questo non è del tutto corretto in quanto ignora -e +prima ...

Ora usiamo:

Object.is(+0, -0) //false

Come vedi, questo è più accurato da confrontare.

Anche in questo caso NaNfunziona più come corretto, considerando comunque NaNlo stesso.

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.