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

Выход этого кода: fail. Зачем?(! [] + []) [+ []] ... Объясните, почему это работает

Кстати, (![]+[])[+!+[]] == 'false'[1], справа ?. Но почему ![]+[] == "false" и почему +!+[] == 1?

+13

@Snoob Я вам не доверяю. В конце концов, это вилочная бомба. –

+0

: |. Это только код js, я не могу причинить вам вреда. – Snoob

+3

Это, конечно, строковый литерал;) –

ответ

116

Как @Mauricio прокомментировал (![]+[])[+[]] является "е" (первый символ из "ложь"), (![]+[])[+!+[]]) является "а", и т.д ...

Как это работает?

Давайте рассмотрим первый символ «F»:

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

Первая часть выражения-между скобками, состоит ![]+[], первый операнд оператора сложения ![] и он будет производить false , потому что объект массива - как и любой другой экземпляр объекта - равен правдой и применяет логический (!) НЕ унарный оператор, он производит, например, значение false.

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

После этого, у нас есть второй операнд сложения, пустой массив, [], это сделано только для преобразования значения в строку false, так как строковое представление пустого массива это просто пустая строка , что эквивалентно:

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

последняя часть, пара квадратных скобок после скобок, они являются собственностью сбруя, и они получают выражение, которое образовано в одноместной Plus оператора применяется в пустой массив еще раз.

Что делает Унарное Plus Оператор преобразования типа, в Number, например:

typeof +"20"; // "number" 

Еще раз, это применяется к пустому массиву, и, как я уже говорил, строковое представление Массив является пустой строкой, а при преобразовании пустой строки в номер, он преобразуется в ноль:

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

Поэтому мы можем «декодировать» выражение в несколько шагов:

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

Обратите внимание, что доступ к символам с использованием нотации в скобках для значений String не был частью ECMAScript 3rd. Edition Specification, (поэтому существует метод charAt).

Однако этот тип «свойств индекса», который представляет символы строки, был стандартизован на ECMAScript 5, и даже до стандартизации эта функция была доступна в большом количестве браузеров (даже в IE8 (режим стандартов)).

+39

Надеюсь, это никогда не вопрос для интервью. – Inisheer

+4

@JTA: я надеюсь, что это * есть *! Я бы прошел: -D –

+1

! + [] -> почему это правда? – Snoob

Смежные вопросы