我正在阅读这些slides,我找到了以下javascript行:
({} + [])[!![] + !![] + !![]] + (![] + [])[!![] + !![] + !![]]
如果您在控制台执行此行,将返回“js”。 更改代码会使行返回不同的字母。我几乎可以回复我的名字(缺少“n”):
({} + [])[!![] + !![] + !![]] + (![] + {})[!![] + !![] + !![] + !![]] + (![] + {})[![] + !![] ]
为什么会这样?这是如何工作的?幻灯片没有提供太多信息。
答案 0 :(得分:2)
{} + []
:当+
的操作数不是数字时,它会在两个操作数上调用toString
并连接它们的值。 {}.toString()
返回[object Object]
,[].toString()
返回数组的内容,该数组只是一个空字符串,因为数组不包含任何内容:
("[object Object]" + "")[!![] + !![] + !![]] + (![] + [])[!![] + !![] + !![]]
==>
"[object Object]"[!![] + !![] + !![]] + (![] + [])[!![] + !![] + !![]]
当[]
转换为布尔值时,它返回true。如果逻辑!!
的操作数与undefined
,null
,0
或空字符串""
不匹配,则返回true。因此!![]
返回true。
当对布尔值进行算术运算时,执行整数提升。值true
和false
分别转换为1
和0
:
"[object Object]"[true + true + true] + (![] + [])[true + true + true]
==>
"[object Object]"[1 + 1 + 1] + (![] + [])[1 + 1 + 1]
==>
"[object Object]"[3] + (![] + [])[3]
下标运算符[n]
获取类似数组结构的(n + 1)-th
成员(因为数组是0索引的)。第一个[3]
获取字符串的第4个字符"j"
:
"j" + (![] + [])[3]
![]
返回false(因为[]
是真实的)而[]
返回一个空字符串:
"j" + (false + "")[3]
==>
"j" + "false"[3]
"false"
中的第4个字符是" s" (数组为0索引)。所以这解决了:
"j" + "s"
==> "js"
答案 1 :(得分:1)
如果仔细观察,有两件事情发生,一件是添加一个空对象和一个数组,另一件是索引器。
在JS中,{} + []
返回0
({} + [])
返回“[object Object]”
[] + {}
返回“[object Object]”
![] + {}
返回“false [object Object]”
(![] + [])
返回“false”
此外,由于所有内容都是类型可转换的,true+true
= 2(true等于1)。 !![]
将返回true
(布尔值),因此!![] + !![] + ![]
与执行true + true + true
相同,等于3。
因此,为此,您将评估以字符串形式出现的内容,然后对这些字符串进行索引以获取单个字符。你有“假”和“对象”这两个词可供选择。