(! [] + []) [+ []]… Wyjaśnij, dlaczego to działa


107
alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]);

Wyjście z tego kodu jest: fail. Czemu?

Nawiasem mówiąc (![]+[])[+!+[]] == 'false'[1], prawda? Ale dlaczego ![]+[] == "false"i dlaczego +!+[] == 1?


14
@Snoob Nie ufam ci. W końcu to bomba widelca.
Johannes Schaub - litb

3
Jest to oczywiście ciąg znaków;)
Yi Jiang

3
(![]+[])[+[]]to „f” (pierwszy znak od „false”), (![]+[])[+!+[]]to „a” itd.
Mauricio Scheffer

3
@Snoob: jak powiedziałeś, możesz przetestować każde wyrażenie w swojej przeglądarce. Spróbuj, alert(![]+[])a alert(+!+[])zobaczysz.
Mauricio Scheffer

12
Bezużyteczne czy nie, uważam to za interesujące pytanie i chciałbym zobaczyć dobrze sformułowane wyjaśnienie. Wiele golfów Code zostałoby zamkniętych, gdyby wziąć pod uwagę użyteczność lub praktyczność. Ćwiczenia i gry są przydatne same w sobie, aby rozwinąć umysł i proces myślenia.
John K

Odpowiedzi:


127

Jak skomentował @Mauricio, (![]+[])[+[]]to „f” (pierwszy znak wyrażenia „false”), (![]+[])[+!+[]])to „a” itd.

Jak to działa?

Przeanalizujmy pierwszy znak, „f”:

(![]+[])[+[]]; // 'f'

Pierwsza część wyrażenia - w nawiasach - jest utworzona przez ![]+[], pierwszy operand operatora dodawania jest ![]i będzie produkowany false, ponieważ obiekt tablicy - jak każda inna instancja Object - jest prawdziwy i stosuje jednoargumentowy Logiczny (!) NIE operator, generuje falsena przykład wartość .

![]; // false, it was truthy
!{}; // false, it was truthy
!0;  // true, it was falsey
!NaN;  // true, it was falsey

Po nim mamy drugi operand dodawania, pusty Array, który []jest tworzony tylko po to, aby przekonwertować falsewartość na String, ponieważ reprezentacja ciągu pustej tablicy jest po prostu pustym ciągiem, jest równoważna:

false+[]; // "false"
false+''; // "false"

Ostatnia część, para nawiasów kwadratowych po nawiasach, są akcesoriami właściwości i otrzymują wyrażenie, które jest tworzone przez jednoargumentowy operator plus zastosowany ponownie do pustej tablicy.

To, co robi Unary Plus Operator, to konwersja typów Number, na przykład:

typeof +"20"; // "number"

Jeszcze raz jest to stosowane do pustej tablicy i, jak powiedziałem wcześniej, reprezentacja ciągu w tablicy jest pustym ciągiem, a kiedy konwertujesz pusty ciąg na Number, jest konwertowany na zero:

+[]; // 0, because
+[].toString(); // 0, because
+""; // 0

Dlatego możemy "dekodować" wyrażenie w kilku krokach:

(![]+[])[+[]];
(false+[])[+[]];
(false+'')[+[]];
(false+'')[0];
('false')[0];  // "f"

Należy zauważyć, że uzyskiwanie dostępu do znaków przy użyciu notacji nawiasów w wartościach typu String nie było częścią trzeciego skryptu ECMAScript. Specyfikacja wydania (dlatego charAtistniała metoda).

Jednak tego rodzaju „właściwości indeksu”, które reprezentują znaki łańcucha, zostały ustandaryzowane w ECMAScript 5, a nawet przed standaryzacją funkcja była dostępna w wielu przeglądarkach (nawet w IE8 (tryb standardowy)).


46
Mam tylko nadzieję, że to nigdy nie jest pytanie do wywiadu.
Inisheer

4
@JTA: Mam nadzieję, że tak ! Zdałbym :-D
Mauricio Scheffer

18
Skąd pochodzi „i”?
Josh Stodola

5
@rlemon, w języku nie ma inttypu danych, w rzeczywistości wszystkie liczby są w 64-bitowym formacie podwójnej precyzji (wartości IEEE 754), mimo że niektóre operatory działają wewnętrznie z wartościami całkowitymi (jak operatory bitowe) wynik jest zawsze podwójny . W 'i'tym przykładzie pochodzi z undefined, ale może pochodzić Infinityna przykład: (+!+[]/+[+[]]+[])[!+[]+!+[]+!+[]]=> (1/0+'')[3]=> (Infinity+'')[3]=>'i'
CMS

5
@JoshStodola Cóż, ~ 3 miesiące później, dalsze wyjaśnienie. „I” w tym przypadku pochodzi od „undefined”, tak, ale jest tu jeszcze jedna sztuczka. Kod łączy „fałsz” z „nieokreślonym” do postaci "falseundefined"(skonstruowanej przy użyciu [![]]+[][[]]:), w której indeks „i” wynosi 10. +!+[]+[+[]]daje "10". Służy do wyodrębnienia „i” (indeksy łańcuchowe mogą być używane w javascript, jeśli można je najwyraźniej przekształcić w liczby całkowite). Ostateczna konstrukcja, która go tworzy, to:([![]]+[][[]])[+!+[]+[+[]]]
entropia
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.