Очень спорный вопрос для собеседования, откровенно говоря.
Операторы сложения и вычитания имеют унарную версию: употребление такого оператора перед значением конвертирует значение в числовое.
console.log(+"1"); // prints 1
console.log(+"s"); // prints NaN
В случае
+[]
, что эквивалентно Number([]), массив преобразуется в 0. Соответственно в операции
!+[]
используется 2 оператора подряд (например, как !! во второй части выражения), сначала происходит преобразование массива в ноль с помощью унарного оператора сложения
+[]
и конвертация нуля в true с помощью оператора
!
. В первой части выражения получаем true.
Массив рассматривается как
truthy значение, сл-но двойной оператор not во второй части выражения дает значение true (грубо говоря, это способ конвертировать массив в булевый тип).
В итоге
(!(+[])) + (!![])
(я позволил себе расставить скобки, чтобы был более очевиден порядок выполнения), конвертится в
true + true
, что конвертится в 1 + 1, собственно, вот и ваша двойка.
ps Я хз, люди, которые составляют такие задачи, видимо, просто глумятся.
более наглядная последовательность преобразований:
!+[] + !![];
/* +[] converts to 0 */
!0 + !![];
/* !0 converts to true */
true + !![];
/* ![] converts to false */
true + !false;
/* !false coverts to true */
true + true;
/* both true values convert to numbers */
1 + 1;
/* equals 2 */
Небольшой апдейт. На немой вопрос "почему конвертация массива в число дает 0, а конвертация массива в булевой тип дает true, тогда как true != 0?" можно ответить след. образом:
а) Почему конвертация массива в число дает 0? Массив является объектом в js, для конвертации объекта в число его нужно сначала конвертировать в примитив. В данном случае для простого объекта вызывается метод toString(). Метод toString() на массиве возвращает конкатенацию строковых значений массива, что для пустого массива дает пустую строку "". Подробнее о логике конвертации объекта в примитив в спеке,
ecma-262/5.1/9.1. Далее конвертируется строка в число, что для пустой строки равно 0, подробнее
пункт 9.3.1 спеки.
б) Почему конвертация массива в булевый тип дает true? Простой ответ: согласно
пункту 9.2 спецификации. Если поразмышлять, то скорее всего это означает, что объект существует (а он не может не существовать, если существует ссылка на него).