2015-12-30 16 views
22

Próbuję zrozumieć wyrażenie {} == true po sekcji 7.2.12 dokumentu Ecma-262.Jak rozumieć wyrażenie "{} == true"?

  1. Jeśli typ (y) jest logiczną, zwraca wynik porównania x == ToNumber(y)

Wynikiem ToNumber(true) jest 1, następnie

{} == 1

  1. Jeśli Typ (x) to Obiekt i typ (y) to Ciąg, Liczba lub Symbol, a następnie zwraca wynik porównania ToPrimitive(x) == y.

Jestem teraz zdezorientowany na ToPrimitive({}).

  1. Jeśli wskazówka jest "string", to

    a. Niech methodNames będzie "" toString "," valueOf "».

  2. Else

    a. Niech methodNames będzie "" valueOf "," toString "».

Gdyby ToPrimitive({}) być interpretowane jako {}.toString() lub {}.valueOf()?

Załóżmy, że wywoływana jest nazwa toString().

Jeśli Type (x) jest String i typ (y) jest liczba, zwróci wynik porównania ToNumber(x) == y

Więc {} == true może być ToNumber(ToPrimitive({})) == ToNumber(true)?

+2

Lista 'methodNames' jest listą priorytetów – Hacketo

+0

" * może ktoś podać więcej szczegółów * "brzmi zbyt szeroko dla SO. Co chcesz wiedzieć? – Bergi

+0

@Bergi Dostaję trochę informacji z odpowiedzi "Dmitri Pavlutin". Masz rację, zaktualizuję moje pytanie. – zangw

Odpowiedz

15

The spec mówi:

Kiedy ToPrimitive nazywa się bez śladu, to generalnie zachowuje się tak, jakby były Ilość podpowiedź.

Dlatego zgodnie z algorytmem ToPrimitive, valueOf jest wywoływana jako pierwsza. Ale ponieważ zwraca obiekt, a nie prymitywną wartość, zostanie nazwany drugi, który zwraca ciąg znaków.

Więc {} == true może być ToNumber(ToPrimitive({})) == ToNumber(true)?

Tak, dokładnie tak jest.

+0

Czy mógłbyś podać więcej szczegółów na temat 'ToNumber (ToPrimitive ({})) == ToNumber (true)'? – zangw

+1

Co dokładnie chcesz wiedzieć? Myślałem, że wiesz, co robią funkcje? –

+1

Dostaję pewne szczegóły z odpowiedzi @Dmitri Pavlutin. – zangw

7

ToPrimitive({}) najpierw ocenia się na {}.valueOf(). Ponieważ valueOf() zwraca sam obiekt, używana jest metoda toString().
{}.toString() zwraca "[object Object]", który jest porównywany z 1. "[object Object]" został przekształcony na numer NaN i porównany z 1.
Teraz operandy są tego samego typu Liczba i używany jest operator ===. NaN === 1 ocenia się na false.

Formalnie:

  1. {} == true (przekształcić true do Number ->1)
  2. {} == 1 (przekształcić {} z wykorzystaniem valueOf(), następnie toString() ->"[object Object]")
  3. "[object Object]" == 1 (przekształcić "[object Object]" do Number - >NaN)
  4. NaN == 1 (zmienić operatora === powodu argumentami są te same typy)
  5. NaN === 1
  6. false

Aktualizacja: Sprawdź mój post The legend of JavaScript equality operator o wiele więcej szczegółów i przykładów.

+0

To, co wspomniałem w pytaniu, to '==', a nie '===', więc 'NaN === 1'? – zangw

+1

@zangw, NaN w każdym porównaniu zwraca false – Grundy

+1

@zangw Ponieważ == transformuje najpierw operandy na ten sam typ, a na końcu następuje === (NaN i 1 są tym samym typem Number). W prostych słowach przy użyciu ==, w końcu === jest i tak używane po transformacji do tego samego typu. –