Object.is vs ===

141

Natknąłem się na przykład kodu, który korzystał z tego porównania:

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

Wiem, że false == 0tak będzie true, dlatego mamy ===.

Czym się Object.isróżni od ===?

JS-JMS-WEB
źródło

Odpowiedzi:

174

===w JavaScript nazywa się operatorem ścisłego porównania. Object.isi operator ścisłego porównania zachowują się dokładnie tak samo z wyjątkiem NaNi +0/-0.

Z MDN:

Object.is()metoda to nie to samo, co bycie równym według ===operatora. ===Operatora (i ==napędu i) traktuje wartości liczby -0 i +0 jako równe i traktuje Number.NaNjako nierówne NaN.

Poniższy kod podkreśla różnicę między ===i 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

wprowadź opis obrazu tutaj

Więcej przykładów znajdziesz tutaj .

Uwaga : Object.isjest częścią propozycji ECMAScript 6 i nie jest jeszcze szeroko obsługiwany (np. Nie jest obsługiwany przez żadną wersję Internet Explorera lub wiele starszych wersji innych przeglądarek). Możesz jednak użyć wypełniacza dla przeglądarek innych niż ES6, który można znaleźć w linku podanym powyżej.

Gurpreet Singh
źródło
26
Prawdopodobnie w pierwszym wierszu odpowiedzi powinno być „Zachowują się dokładnie tak samo, z wyjątkiem NaN oraz +0 i -0”.
Benjamin Gruenbaum
1
@BenjaminGruenbaum Dobra sugestia. Sprawia, że ​​odpowiedź jest łatwiejsza do odczytania. Twoje zdrowie.
Gurpreet Singh
3
@ humble.rumble zostało to szczegółowo omówione - metody statyczne są prostsze - nie mają problemów z kontekstem ani problemów prymitywnych. Na przykład w twoim przykładzie spodziewałbym się fałszu, ale początkujący w JS spodziewaliby się prawdy, ponieważ wykonanie .xna łańcuchu umieszcza go w Stringobiekcie (a nie w wartości pierwotnej ciągu), a porównanie byłoby między obiektem a ciągiem - to jest bardzo subtelne i jest pułapką - statystyka pozwala uniknąć tych problemów, metody statyczne są prostsze i łatwiejsze w użyciu.
Benjamin Gruenbaum
2
@ humble.rumble Aby porównać węzły DOM, istnieje już taka metoda, zobacz isEqualNode . Przykład:document.createElement('div').isEqualNode(document.createElement('div')) === true
Rob W
2
Aktualizacja 2017: Object.is () jest teraz szeroko obsługiwany we wszystkich głównych przeglądarkach.
Sterling Bourne
56

Object.isużywa algorytmu SameValue specyfikacji , podczas gdy ===używa algorytmu Strict Equality Algorithm . Uwaga na temat algorytmu ścisłej równości zwraca uwagę na różnicę:

Ten algorytm różni się od algorytmu SameValue ... sposobem traktowania zer ze znakiem i NaN.

Zauważ, że:

  • NaN === NaNjest fałszywe, ale Object.is(NaN, NaN)jest prawdziwe
  • +0 === -0jest prawdziwe, ale Object.is(+0, -0)jest fałszywe
  • -0 === +0jest prawdziwe, ale Object.is(-0, +0)jest fałszywe

JavaScript ma co najmniej cztery rodzaje „równości”:

  • „Loose” ( ==), gdzie operandy zostaną wymuszone, aby spróbować je dopasować. Zasady są jasno określone , ale nieoczywiste. ( "" == 0jest true; "true" == truejest false, ...).
  • „Ścisłe” ( ===), gdzie operandy różnych typów nie będą wymuszane (i nie będą równe), ale zobacz uwagę powyżej NaNoraz dodatnie i ujemne zero.
  • SameValue - jak wymieniono powyżej (używane przez Object.is).
  • SameValueZero - jak SameValuez wyjątkiem +0i -0są takie same zamiast różnych (używane przez Mapdla kluczy i przez Array.prototype.includes).

Istnieje również równoważność obiektów , która nie jest zapewniana przez sam język lub środowisko wykonawcze, ale jest zwykle wyrażana jako: Obiekty mają ten sam prototyp, te same właściwości, a ich wartości właściwości są takie same (według rozsądnej definicji „takie same” ).


Algorytm SameValue :

  • Jeśli Type (x) różni się od Type (y), zwróć false.
  • Jeśli Type (x) to Number, to
    • Jeśli x jest NaN, a y jest NaN, zwraca prawdę.
    • Jeśli x to +0, a y to -0, zwróć false.
    • Jeśli x to -0, a y to +0, zwróć false.
    • Jeśli x jest tą samą wartością Number co y, zwraca true.
    • Zwróć fałsz.
  • Zwraca SameValueNonNumber (x, y).

... gdzie SameValueNonNumber to:

  • Assert: Type (x) nie jest Number.
  • Assert: Type (x) jest taki sam jak Type (y).
  • Jeśli Type (x) ma wartość Undefined, zwraca true.
  • Jeśli Type (x) ma wartość Null, zwraca wartość true.
  • Jeśli Type (x) to String, to
    • Jeśli x i y to dokładnie ta sama sekwencja jednostek kodu (ta sama długość i te same jednostki kodu przy odpowiednich indeksach), zwraca wartość true; w przeciwnym razie zwraca false.
  • Jeśli Type (x) jest Boolean, to
    • Jeśli x i y są zarówno prawdziwe, jak i oba fałszywe, zwraca prawdę; w przeciwnym razie zwraca false.
  • Jeśli Type (x) to Symbol, to
    • Jeśli x i y są tą samą wartością Symbol, zwraca prawdę; w przeciwnym razie zwraca false.
  • Zwraca prawdę, jeśli x i y są tą samą wartością Object. W przeciwnym razie zwróć false.

Algorytm ścisłej równości :

  1. Jeśli Type (x) różni się od Type (y), zwróć false.
  2. Jeśli Type (x) to Number, to
    • Jeśli x jest NaN, zwraca false.
    • Jeśli y jest NaN, zwraca false.
    • Jeśli x jest tą samą wartością Number co y, zwraca true.
    • Jeśli x to +0, a y to -0, zwraca prawdę.
    • Jeśli x to -0, a y to +0, zwraca prawdę.
    • Zwróć fałsz.
  3. Zwraca SameValueNonNumber (x, y).
TJ Crowder
źródło
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;
}

Powyżej jest funkcją polyfill, która pokazuje, jak Object.isdziała, dla każdego, kto jest zainteresowany. Odniesienie do You-Don't-Know-JS

Izaak
źródło
2

Podsumowanie:

Object.is()Funkcja przyjmuje wartości 2 jako argumenty i zwraca true, jeśli 2 Podane wartości są dokładne takie same, w przeciwnym razie będzie to return false.

Dlaczego tego potrzebujemy?

Możesz pomyśleć, że mamy już ścisłą równość (sprawdza typ + wartość) sprawdzanie w javascript z ===operatorem, po co nam ta funkcja? Cóż, ścisła równość nie jest wystarczająca w niektórych przypadkach i są one następujące:

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

Object.is() pomaga nam, ponieważ jest w stanie porównać te wartości, aby zobaczyć, czy są podobne, czego operator ścisłej równości nie może zrobić.

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

Willem van der Veen
źródło
0

Krótko mówiąc, są podobne, ale Object.issą mądrzejsze i dokładniejsze ...

Spójrzmy na to ...

+0 === -0 //true

Ale to nie jest w pełni słuszne, ponieważ ignoruje -i +przed ...

Teraz używamy:

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

Jak widać, porównanie jest dokładniejsze.

Również w tym przypadku NaNdziała bardziej jak poprawne, rozważ NaNto samo.

Alireza
źródło