Synoon
Synoon

Reputation: 2351

why resolve this "b" == ([] +{})[!+[]<<!+[]]) to true

Can anyone explain this?

console.log("b" == ([] +{})[!+[]<<!+[]])

I can imagine it has something to do with type conversion. but the <<! get me really confused

Upvotes: 1

Views: 65

Answers (2)

Code Maniac
Code Maniac

Reputation: 37755

Let's understand it step by

When you do arithmetic opreation on array it internally calls toString

console.log([]+ 1, typeof ([] + 1))

so the ([]+{}) will result in "[object Object]"

console.log([] +{})

When you use + unary operator which tries to change the operand to numeric values

console.log(+[])

so now

(!+[] << !+[]) which is equal to ` 1 << 1`, so left shifts result in `2`

SO your simplified expression is

console.log("b" == "[object Object]"[2] )


This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right. Left shift MDN

so 1 is represent as 01 in binary, so 1 << 1 will shift the binary by 1 position so it will become

`10`  -> in binary representation, 

Which is equal to 2 in decimal format

console.log(1<<1)
console.log((2).toString(2))
console.log(parseInt("10",2))

Upvotes: 3

CertainPerformance
CertainPerformance

Reputation: 371019

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`.

Upvotes: 4

Related Questions