Niedawno odkryłem to 2 == [2]
w JavaScript. Jak się okazuje, to dziwactwo ma kilka interesujących konsekwencji:
var a = [0, 1, 2, 3];
a[[2]] === a[2]; // this is true
Podobnie działa:
var a = { "abc" : 1 };
a[["abc"]] === a["abc"]; // this is also true
Co jeszcze dziwniejsze, to też działa:
[[[[[[[2]]]]]]] == 2; // this is true too! WTF?
Te zachowania wydają się spójne we wszystkich przeglądarkach.
Masz jakiś pomysł, dlaczego jest to funkcja języka?
Oto bardziej szalone konsekwencje tej „funkcji”:
[0] == false // true
if ([0]) { /* executes */ } // [0] is both true and false!
var a = [0];
a == a // true
a == !a // also true, WTF?
Te przykłady zostały znalezione przez sławę jimbojw http://jimbojw.com oraz walkingeyerobot .
źródło
+"2"
jest również numerem 2.Po prawej stronie równania mamy a [2], która zwraca typ liczbowy o wartości 2. Po lewej stronie najpierw tworzymy nową tablicę z jednym obiektem o wartości 2. Następnie wywołujemy a [( tablica jest tutaj)]. Nie jestem pewien, czy daje to ciąg, czy liczbę. 2 lub „2”. Najpierw weźmy wielkość liter. Uważam, że ["2"] utworzy nową zmienną i zwróci wartość null. null! == 2. Załóżmy więc, że faktycznie jest to niejawna konwersja na liczbę. a [2] zwróciłoby 2. 2 i 2 pasujące pod względem typu (więc === działa) i wartości. Myślę, że jest to niejawna konwersja tablicy na liczbę, ponieważ [wartość] oczekuje ciągu lub liczby. Wygląda na to, że liczba ma wyższy priorytet.
Na marginesie, zastanawiam się, kto decyduje o tym pierwszeństwie. Czy dlatego, że [2] ma liczbę jako pierwszą pozycję, więc jest konwertowana na liczbę? A może jest tak, że podczas przekazywania tablicy do [tablicy] próbuje najpierw przekształcić tablicę w liczbę, a następnie w łańcuch. Kto wie?
W tym przykładzie tworzysz obiekt o nazwie a z elementem o nazwie abc. Prawa strona równania jest dość prosta; jest odpowiednikiem a.abc. Zwraca to 1. Lewa strona najpierw tworzy dosłowną tablicę ["abc"]. Następnie wyszukujesz zmienną w obiekcie, przekazując nowo utworzoną tablicę. Ponieważ oczekuje ciągu, konwertuje tablicę na ciąg. To teraz daje ["abc"], które jest równe 1. 1 i 1 są tego samego typu (dlatego === działa) i mają taką samą wartość.
To jest tylko niejawna konwersja. === nie zadziała w tej sytuacji, ponieważ występuje niezgodność typów.
źródło
==
dotyczyToPrimitive()
tablicy, która z kolei wywołuje swojątoString()
metodę, więc to, co faktycznie porównujesz, to liczba2
do łańcucha"2"
; Porównanie między łańcuchem a liczbą odbywa się poprzez konwersję łańcuchaW tym
==
przypadku Doug Crockford zaleca zawsze używanie===
. Nie wykonuje żadnej niejawnej konwersji typu.W przykładach with
===
niejawna konwersja typów jest wykonywana przed wywołaniem operatora równości.źródło
To ciekawe, w rzeczywistości nie jest tak, że [0] jest zarówno prawdziwe, jak i fałszywe
Jest to zabawny sposób przetwarzania operatora if () w javascript.
źródło
==
działa w zabawny sposób ; jeśli użyjesz rzeczywistego, jawnego rzutowania (tj.Boolean([0])
lub!![0]
), przekonasz się, że w kontekstach logicznych[0]
będzie to obliczanetrue
tak, jak powinno: w JS każdy obiekt jest uważany zatrue
Tablicę jednego elementu można traktować jak sam element.
Wynika to z pisania kaczkami. Ponieważ "2" == 2 == [2] i prawdopodobnie więcej.
źródło
==
operatora przed porównaniem.Aby dodać trochę szczegółów do innych odpowiedzi ... porównując an
Array
do aNumber
, Javascript przekonwertujeArray
zparseFloat(array)
. Możesz spróbować samemu w konsoli (np. Firebug lub Web Inspector), aby zobaczyć, na jakie różneArray
wartości zostaną przekonwertowane.Dla
Array
sparseFloat
wykonuje operację naArray
pierwszym składniku, a resztę odrzuca.Edycja: według szczegółów Christopha może się zdarzyć, że wewnętrznie używa dłuższej formy, ale wyniki są konsekwentnie identyczne
parseFloat
, więc zawsze możesz użyćparseFloat(array)
skrótu, aby wiedzieć na pewno, w jaki sposób zostanie przekonwertowany.źródło
Porównujesz 2 obiekty w każdym przypadku .. Nie używaj ==, jeśli myślisz o porównaniu, masz na myśli ===, a nie ==. == często daje szalone efekty. Szukaj dobrych części w języku :)
źródło
Wyjaśnienie do sekcji EDYCJA pytania:
Pierwszy przykład
Pierwszy typ [0] do wartości pierwotnej, zgodnie z odpowiedzią Christopha powyżej, mamy „0” (
[0].valueOf().toString()
)Teraz wpisz Boolean (false) na Number, a następnie String („0”) na Number
Jeśli chodzi o
if
stwierdzenie, jeśli nie ma wyraźnego porównania w samym warunku if, warunek jest oceniany jako prawdziwy wartości.Jest tylko 6 fałszywych wartości : false, null, undefined, 0, NaN i pusty ciąg „”. A wszystko, co nie jest wartością fałszywą, jest wartością zgodną z prawdą.
Ponieważ [0] nie jest fałszywą wartością, jest prawdziwą wartością, wynikiem
if
instrukcji jest prawda i ją wykonuje.2. przykład
Ponownie wpisz rzutowanie wartości na prymitywne,
źródło