如果我们将其拆分,则混乱等于:
++[[]][+[]]+[+[]]
在Javascript中,确实是这样
+[]===0。
+将某物转换为数字,在这种情况下,它将降为
+""或
0(请参见下面的规范详细信息)。
因此,我们可以简化它(
++优先于
+):
++[[]][0]+[0]
因为
[[]][0]意思是:从中获取第一个元素
[[]],所以确实:
[[]][0]返回内部数组(
[])。由于引用,说错了
[[]][0]===[],但是让我们调用内部数组
A以避免错误的表示法。
++在其操作数之前表示“加1并返回加结果”。因此
++[[]][0]等于
Number(A) + 1(或
+A + 1)。
同样,我们可以将混乱简化为更清晰的内容。让我们替换
[]为
A:
(+[] + 1)+[0]
在
+[]将数组强制转换为number之前
0,需要先将其强制转换为字符串,即
""再次。最后
1添加,结果为
1。
(+[] + 1) === (+"" + 1)
(+"" + 1) === (0 + 1)
(0 + 1) === 1
让我们进一步简化一下:
1+[0]
同样,在Javascript:中也是如此
[0]=="0",因为它是将一个元素与一个数组连接在一起。连接将连接由分隔的元素
,。使用一个元素,您可以推断出此逻辑将导致第一个元素本身。
在这种情况下,
+将看到两个操作数:一个数字和一个数组。现在,它试图将两者强制转换为同一类型。首先,将数组强制转换为字符串
"0",然后将数字强制转换为字符串(
"1")。
Number
+字符串
===String。
"1" + "0" === "10" // Yay!
规格详细信息
+[]:
这
+[]真是一个迷宫,但要做到这一点,首先要将其转换为字符串,因为这是这样
+说的:
11.4.6一元+运算符
一元+运算符将其操作数转换为Number类型。
产生Unaryexpression:+ Unaryexpression的评估如下:
令expr为评估Unaryexpression的结果。
返回ToNumber(GetValue(expr))。
Tonumber()说:
宾语
应用以下步骤:
令primValue为ToPrimitive(输入参数,提示字符串)。
返回ToString(primValue)。
ToPrimitive()说:
宾语
返回对象的默认值。通过调用对象的[[DefaultValue]]内部方法并传递可选提示PreferredType来检索对象的默认值。本规范为8.12.8中的所有本机ECMAscript对象定义了[[DefaultValue]]内部方法的行为。
[[DefaultValue]]说:
8.12.8 [[DefaultValue]](提示)
使用提示字符串调用O的[[DefaultValue]]内部方法时,将执行以下步骤:
令toString为使用参数“ toString”调用对象O的[[Get]]内部方法的结果。
如果IsCallable(toString)为true,
一个。令str为调用toString的[[Call]]内部方法的结果,其中O为this值,并且参数列表为空。
b。如果str是原始值,则返回str。
该
.toString数组的说:
15.4.4.2 Array.prototype.toString()
调用toString方法时,将执行以下步骤:
令array为在this值上调用ToObject的结果。
令func为使用参数“ join”调用array的[[Get]]内部方法的结果。
3.
如果IsCallable(func)为false,则将func设为标准的内置方法Object.prototype.toString(15.2.4.2)。
- 返回调用func提供数组的[[Call]]内部方法的结果作为this值和空参数列表。
所以
+[]归结为
+"",因为
[].join() === ""。
同样,
+定义为:
11.4.6一元+运算符
一元+运算符将其操作数转换为Number类型。
产生Unaryexpression:+ Unaryexpression的评估如下:
令expr为评估Unaryexpression的结果。
返回ToNumber(GetValue(expr))。
ToNumber被定义为
"":
StringNumericLiteral ::: [空]的MV为0。
如此
+"" === 0,如此
+[] === 0。


![为什么++ [[]] [+ []] + [+ []]返回字符串“ 10”? 为什么++ [[]] [+ []] + [+ []]返回字符串“ 10”?](http://www.mshxw.com/aiimages/31/407926.png)
