这是有效的,并在JavaScript中返回字符串“10”(此处有更多示例):
控制台日志(++[[]][+[]]+[+[]])
为什么?这里发生了什么?
这是有效的,并在JavaScript中返回字符串“10”(此处有更多示例):
控制台日志(++[[]][+[]]+[+[]])
为什么?这里发生了什么?
当前回答
一元加给定字符串转换为数字增量运算符给定的字符串转换并递增1[] == ''. 空字符串+“”或+[]的值为0。++[[]][+[]]+[+[]] = 10 ++[“”][0]+[0]:第一部分给出数组的第零个元素,该元素为空字符串1+0 10
其他回答
++[ [] ][+[]] === 1+[] === 0++[ [] ][0] === 1[+[]]是[0]
然后我们有一个字符串连接:
1+字符串([0])==10
+[]计算结果为0[…]然后将其与任何东西相加(+运算),将数组内容转换为由逗号连接的元素组成的字符串表示。
任何其他的东西,比如数组的索引(比+操作的优先级更高)都是有序的,没有什么有趣的。
将表达式求值为不带数字的“10”的最短可能方法是:
+!+[] + [+[]] // "10"
-~[] + [+[]] // "10"
解释
+!+[]:+[]的值为0。!0的计算结果为true。+true被评估为1。-~[]与求值为1的-(-1)相同。[+[]]:+[]评估为0[0]是具有单个元素0的数组。
然后,JS计算1+[0],一个Number+Array表达式。然后ECMA规范起作用:+运算符通过调用ToPrimitive和ToString抽象操作将两个操作数转换为字符串。如果表达式的两个操作数都是数字,则它作为加法函数运行。诀窍是数组很容易将它们的元素强制转换为连接的字符串表示。
一些示例:
1 + {} // "1[object Object]"
1 + [] // "1"
1 + new Date() // "1Wed Jun 19 2013 12:13:25 GMT+0400 (Caucasus Standard Time)"
[] + [] // ""
[1] + [2] // "12"
{} + {} // "[object Object][object Object]" ¹
{a:1} + {b:2} // "[object Object][object Object]" ¹
[1, {}] + [2, {}] // "1,[object Object]2,[object Object]"
¹:请注意,每一行都是在表达式上下文中计算的。第一个{…}是一个对象文本,而不是一个块,就像语句上下文中的情况一样。在REPL中,您可能会看到{}+}生成NaN,因为大多数REPL在语句上下文中操作;这里,第一个{}是一个块,代码相当于{}+{};, 最终表达式语句(其值成为完成记录的结果)为NaN,因为一元+将对象强制为数字。
让我们简单一点:
++[[]][+[]]+[+[]] = "10"
var a = [[]][+[]];
var b = [+[]];
// so a == [] and b == [0]
++a;
// then a == 1 and b is still that array [0]
// when you sum the var a and an array, it will sum b as a string just like that:
1 + "0" = "10"
这一个评估结果相同,但有点小
+!![]+''+(+[])
[]-是在对数组进行加法或减法时转换为0的数组,因此+[]=0![]-计算结果为false,因此!![]计算结果为true+!![]-将true转换为计算结果为true的数值,因此在本例中为1+“”-将空字符串附加到表达式,使数字转换为字符串+[]-计算结果为0
因此其计算结果为
+(true) + '' + (0)
1 + '' + 0
"10"
现在你明白了,试试这个:
_=$=+[],++_+''+$