2012-06-05 14 views
117

Boot Up Your interpreter/konsolę i spróbuj porównanieDlaczego ",,," == Array (4) w JavaScript?

> ",,," == Array(4) 
True 

Dlaczego? Na początku myślałem, że może skoro można myśleć „,,,” jako tablica czterech znaków z «\ 0» plaster zakończenia, które mogą być, dlaczego, ale

> "..." == Array(4) 

Powroty «fałsz». Więc dlaczego? Wiem, że to trochę idiosynkratyczna wersja pisania na kaczkę w JavaScript, ale ciekawa, co podkreśla to zachowanie. Usprawniono to od doskonałego presentation here btw Zeda Shawa.

+14

Kilka języków poza C używa zerowej końcówki w sposób widoczny dla programisty. – Joey

+7

Jeśli mogę zapytać, co doprowadziło do tego odkrycia? – SomeKittens

+1

@SomeKittens Zed Shaw wspomina o tym wyraźnie w filmie, do którego linkowałem w moim pytaniu (jako krytyka Javascript). Twoje zdrowie! – ZenLikeThat

Odpowiedz

176

Ponieważ prawy operand jest przekształcany do łańcucha i znaków reprezentujący Array(4) jest ,,,:

> Array(4).toString() 
    ",,," 

W przypadku korzystania z funkcji konstruktora array i przekazać numer, ustawia długość tablicy do ten numer. Więc można powiedzieć, masz cztery puste indeksy (podobnie jak [,,,]), a domyślne reprezentację ciąg tablic jest lista oddzielonych przecinkami jej elementów:

> ['a','b','c'].toString() 
    "a,b,c" 

Jak porównanie prac jest opisany w sekcji 11.9.3 of the specification . Nie widać (x == y):

8. Jeśli typ (x) jest albo String lub liczba i typ (y) to obiekt,
powrót wynikiem porównania x = = ToPrimitive (y).

(tablice są obiekty w JavaScript)

i jeśli się metodę ToPrimitive w końcu okaże się, że wymaga ona to toString.

+2

OK, teraz to wszystko ma dla mnie sens. Dzięki. – ZenLikeThat

+6

Co z kolei powoduje, że tablice są uszeregowane tak, jakby używały 'Array.join (", ")'. – duskwuff

+3

Świetna odpowiedź, bardzo precyzyjna. – LoremIpsum

32

Spróbuj użyć ===. Podczas korzystania z wersji == w JavaScript, będzie próbował rzutować zmienne, co prowadzi do problemów takich jak ten. Konsola odrzuca Array(4) do reprezentacji łańcuchowej (tj. Array(4).toString), która jest ",,,". Przyczyną przecinków jest to, że funkcja .toString() dodaje je do osobnych elementów w tablicy.

Zobacz poniższy fragment:

document.write(Array(4).toString());

31

Wewnętrznie jej będzie

",,," == Array(4).toString() 
5

Porównując tablicę na ciąg wymusza na tablicy do łańcucha przed wykonaniem porównania. Wymuszenie pustej 4-elementowej tablicy na łańcuchu daje dokładnie taki ciąg.

17

To dlatego Array(4) inicjalizuje tablicę 4 pustych wartości, == niejawnie konwertuje tak:

",,," == Array(4) 

",,," == Array(4).toString() 

",,," == ["", "", "", ""] // note 3 commas for 4 values 

",,," == ["", "", "", ""].toString() 

są podobne.

== dokonuje niejawnych konwersji typów przed porównaniem wartości, co może skutkować nieprzewidywalnymi rezultatami. Użyj ===, aby sprawdzić typ i wartość.

4

raz pierwszy pomyślałem, że to coś z „prototypem” ... ale po krótkim dochodzeniu doszedłem do smutnego wniosku ...

Najwyraźniej jest to wewnętrzne i bardziej niejasne js co nie było zbyt wiele logiki. ..

spróbuj

Array(4)==Array(4) 

i bez przymusu typów również ...

Array(4)===Array(4) 

a otrzymasz FAŁSZ

wiesz, że null==null, null===null a nawet undefined==undefined i undefined===undefined Zwraca true ... tak ... to nieco niejasne ...

Array(4)==[,,,] powinny być prawdziwe również

+0

ZEE, Array (4) == [,,,] nie będzie prawdą. Jeśli porównamy obiekt z prymitywem, obiekt zostanie przekonwertowany na prymitywny. Oto powód, dla którego wywołuje metodęString(). – devsathish

+0

array (x) powinien być adresem konstruktora ... w każdym razie, w systemie (nie zawracaj sobie głowy jakim systemem), === zawsze będzie prawdą! – ZEE