Как прокомментировал @Mauricio, (![]+[])[+[]]это «f» (первый символ «false»), (![]+[])[+!+[]])это «a» и т. Д.
Как это работает?
Давайте рассмотрим первый символ, "f":
(![]+[])[+[]]; // 'f'
Первая часть выражения, заключенная в круглые скобки, состоит ![]+[]из первого операнда оператора сложения , и ![]он будет порождать false, потому что объект массива - как и любой другой экземпляр объекта - является правдивым , и применение логического (!) НЕ унарного оператор, он false, например , выдает значение .
![]; // false, it was truthy
!{}; // false, it was truthy
!0; // true, it was falsey
!NaN; // true, it was falsey
После него у нас есть второй операнд добавления, пустой массив, []это сделано только для преобразования falseзначения в String, потому что строковое представление пустого массива является просто пустой строкой, что эквивалентно:
false+[]; // "false"
false+''; // "false"
Последняя часть, пара квадратных скобок после скобок, они являются средством доступа к свойствам, и они получают выражение, которое формируется оператором Unary Plus, снова применяемым к пустому массиву.
Оператор Unary Plus выполняет преобразование типов Number, например, в:
typeof +"20"; // "number"
Еще раз, это применяется к пустому массиву, и, как я сказал ранее, строковое представление массива является пустой строкой, и когда вы конвертируете пустую строку в Number, она преобразуется в ноль:
+[]; // 0, because
+[].toString(); // 0, because
+""; // 0
Поэтому мы можем «декодировать» выражение в несколько шагов:
(![]+[])[+[]];
(false+[])[+[]];
(false+'')[+[]];
(false+'')[0];
('false')[0]; // "f"
Обратите внимание, что доступ к символам с использованием обозначения скобок для значений String не был частью ECMAScript 3rd. Спецификация издания, (поэтому charAtметод и существовал).
Однако такого рода «свойства индекса», представляющие символы строки, были стандартизированы в ECMAScript 5, и даже до стандартизации эта функция была доступна в большом количестве браузеров (даже в IE8 (стандартный режим)).