有人可以解释吗?
console.log("b" == ([] +{})[!+[]<<!+[]])
我可以想象它与类型转换有关。但是<<!
让我很困惑
答案 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))