2010-11-13 13 views
92
alert((![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]); 

Die Ausgabe dieses Codes lautet: fail. Warum?(! [] + []) [+ []] ... Erklären Sie, warum das funktioniert

Übrigens, (![]+[])[+!+[]] == 'false'[1], richtig ?. Aber warum ![]+[] == "false" und warum +!+[] == 1?

+13

@Snoob Ich vertraue dir nicht. Am Ende ist es eine Gabelbombe. –

+0

: |. Dies ist nur ein JS-Code, ich kann dir nicht weh tun. – Snoob

+3

Es ist natürlich ein String-Literal;) –

Antwort

116

Als @Mauricio kommentiert (![]+[])[+[]] "f" ist (das erste Zeichen von "false"), (![]+[])[+!+[]]) ist "a", etc ...

Wie funktioniert es?

Lassen Sie uns das erste Zeichen untersuchen, ‚f‘:

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

Der erste Teil des Ausdrucks-Klammern-durch ![]+[] zusammengesetzt, wobei der erste Operand des Additionsoperator ist ![] und es wird false produzieren Da ein Array-Objekt - wie jede andere Objektinstanz - truthy ist und den logischen (!) NICHT unären Operator anwendet, erzeugt es beispielsweise den Wert false.

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

danach, haben wir den zweiten Operanden der Zugabe ein leeres Array, [], dies nur gemacht wird, den false Wert Zeichenfolge zu konvertieren, weil die Stringdarstellung eines leeren Arrays nur ein leerer String ist äquivalent zu:

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

der letzte Teil, das Paar von eckigen Klammern nach den Klammern, sind sie die Eigenschaft Accessor, und sie empfangen einen Ausdruck, der von der unäre plus-Operator auf ein leeres Array gebildet wird, angewendet nochmal.

Was der Unary Plus-Operator tut, ist Typumwandlung, zu Number, zum Beispiel:

typeof +"20"; // "number" 

Noch einmal, dies auf ein leeres Array angelegt wird, und wie ich schon sagte, die String-Darstellung eines Array ist eine leere Zeichenfolge, und wenn Sie eine leere Zeichenfolge Zahl konvertieren, wird es umgewandelt auf Null:

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

Deshalb können wir „entschlüsseln“ den Ausdruck in einigen Schritten:

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

Beachten Sie, dass der Zugriff auf Zeichen mithilfe der Klammernotation für Zeichenfolgenwerte nicht Teil von ECMAScript 3rd war. Editions-Spezifikation, (deshalb existiert die charAt Methode).

Diese Art von "Indexeigenschaften", die die Zeichen eines Strings darstellen, wurden jedoch in ECMAScript 5 standardisiert, und noch vor der Standardisierung war das Feature in einer guten Anzahl von Browsern verfügbar (sogar im IE8 (Standardmodus)).

+39

Hoffe nur, das ist nie eine Interviewfrage. – Inisheer

+4

@JTA: Ich hoffe es * ist *! Ich hätte bestanden :-D –

+1

! + [] -> warum ist es wahr? – Snoob