为什么 (! + [] + [] + ![]).length 是 9
编辑:在底部我添加了我写这篇文章以来所发现的内容。
今天我坐下来思考为什么在 JavaScript 中会得到这样的结果
(! + [] + [] + ![]).length
> 9
于是我打开 JS 控制台,试图弄清楚情况。发现有很多问题:
(!"")
>true
(![])
>false
(!+[])
>true
(!+[]+[])
>"true"
(+[]+"2")
>"02"
([]+"2")
>"2"
我想到的是,我可能对其中一些完全不了解,所以请纠正任何看起来不正确的地方,如下所示。
- JavaScript 从右到左进行操作。
- + 操作数首先尝试将左侧操作数与右侧操作数相加,如果无法相加,则尝试将右侧操作数转换为数字,如果仍无法转换,则将其转换为字符串。如果 + 左侧有值,则将其与右侧操作数相加;如果仍无法转换,则继续进行。如果左侧没有值,则继续进行。
- ! 操作数将右侧的操作数转换为布尔值,然后将其还原。只有以下值与布尔值 false 相同:
false
0
""
null
NaN
undefined
所有其他值都不为假,因此为真。
现在情况是这样的:
// We start with
(! + [] + [] + ![]).length // Remember that we are going from right to left starting
// with the operation before doing -length
![] === false // ! converts the content of [] to true, since it's not part of
// the false group above, and then reverts it.
+ === + // the + is lonely so far with no operand to the right but sticks
// around since it has something on the left.
[]+[] === "" // The contents of [] can't be added or converted to a number so
// the right operand becomes a string. There's still something to
// the left so the + stays.
!+[] === true // This the same as !+0 since +[] is 0
// Now we got:
("false" + "" + false).length
""+false === "false" // + adds "" to false. It then sticks around.
"true" + "" === "true" // The + stays after adding "true" to ""
// ---
("true"++"false")
+"false" ==== "false" // + has nothing but an operand to the left so it goes away.
true + "" === "true" // + adds them together and stays
// ---
("true"+"false")
"true" + "false" === "truefalse" // + still stays
// ---
(+"truefalse")
+"truefalse" === "truefalse" // + has nothing to do after this so it goes away
// ---
("truefalse") // The operation is done so now we are left with what's outside.
"truefalse".length === 9
是的,我确实把每个步骤都做了一遍,甚至包括那些看起来毫无意义的步骤。我完全不确定它是怎么运作的,但对我来说似乎就是这样的。
有什么想法吗?
编辑:
经过评论并查看文档后,我现在知道事情进展如何。
((!(+[]))+[]+(![]))
一元运算符从右到左,因此 !+[] 变为 +[] -> !0 === true。