为什么将这个“ b” ==([] + {})[!+ [] <<!+ []])解析为true

时间:2019-08-29 09:41:39

标签: javascript type-coercion

有人可以解释吗?

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

我可以想象它与类型转换有关。但是<<!让我很困惑

2 个答案:

答案 0 :(得分:4)

细分表达式([] +{})[!+[]<<!+[]],以了解其如何解析为b

([] +{}) [!+[]<<!+[]]

左括号内的表达式解析为[object Object],因为[]{}都被强制转换为字符串(但强制为字符串的空数组为空字符串)。所以现在你有

'[object Object]' [!+[]<<!+[]]

缩小方括号内的表达式:

!+[]<<!+[]

使用operator precedence进行分组,您将得到:

(!+[]) << (!+[])

并且!+[]true+[]尝试将空数组转换为数字,但是将空数组转换为原始数组会导致空字符串,这是错误的,因此数字为0。!颠倒了它的真实性,结果为true。所以

(!+[]) << (!+[])

等同于

true << true

在其数字等效项上按位左移

1 << 1

是2。所以

'[object Object]' [!+[]<<!+[]]

变成

'[object Object]' [2]

或“ b”。

答案 1 :(得分:3)

让我们逐步了解它

对数组进行算术运算时,它会在内部调用toString

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

因此([]+{})将产生"[object Object]"

console.log([] +{})

当您使用+一元运算符试图将操作数更改为数值时

console.log(+[])

现在

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

所以您的简化表达方式是

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


  

此运算符将第一个操作数移位指定的位数   左边。向左偏移的多余位将被丢弃。零位   从右边移入。 Left shift MDN

因此1以二进制形式表示为01,因此1 << 1会将二进制移位1位,从而变为

`10`  -> in binary representation, 

十进制格式等于2

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