Can anyone explain this?
console.log("b" == ([] +{})[!+[]<<!+[]])
I can imagine it has something to do with type conversion. but the <<!
get me really confused
Break down the expression ([] +{})[!+[]<<!+[]]
to see how it resolves to b
:
([] +{}) [!+[]<<!+[]]
The expression inside the left parentheses resolves to [object Object]
, because both the []
and {}
are coerced to strings (but the empty array, coerced to a string, is the empty string). So now you have
'[object Object]' [!+[]<<!+[]]
Break down the expression inside of the square brackets:
!+[]<<!+[]
Group using operator precedence, and you get:
(!+[]) << (!+[])
And !+[]
is true
: +[]
tries to convert the empty array to a number, but turning the empty array to a primitive results in the empty string, which is falsey, so the number is 0. !
inverts the truthyness of that, resulting in true
. So
(!+[]) << (!+[])
is equivalent to
true << true
Which is bitwise left-shift on their numeric equivalents:
1 << 1
which is 2. So
'[object Object]' [!+[]<<!+[]]
turns into
'[object Object]' [2]
or 'b`.