如果我们把它分开,这个混乱就等于:
++[[]][+[]]
+
[+[]]在 JavaScript 中, +[] === 0确实如此。 +将某些东西转换为数字,在这种情况下,它将降为+""或0 (参见下面的规范细节)。 
因此,我们可以简化它( ++优先于+ ): 
++[[]][0]
+
[0]因为[[]][0]表示:从[[]]获取第一个元素,所以: 
[[]][0]返回内部数组( [] )。由于引用说[[]][0] === [] ,但让我们调用内部数组A以避免错误的表示法。 ++[[]][0] == A + 1 ,因为++表示 '递增 1'。 ++[[]][0] === +(A + 1) ; 换句话说,它总是一个数字( +1不一定返回一个数字,而++总是这样 - 感谢 Tim Down 指出这一点)。 同样,我们可以将混乱简化为更清晰的内容。让我们用[]代替A : 
+([] + 1)
+
[0]在 JavaScript 中,这也是正确的: [] + 1 === "1" ,因为[] == "" (加入一个空数组),所以: 
+([] + 1) === +("" + 1) ,和+("" + 1) === +("1") ,和+("1") === 1 让我们进一步简化它:
1
+
[0]此外,在 JavaScript 中也是如此: [0] == "0" ,因为它正在使用一个元素连接数组。加入将通过串联分离的元素, 。使用一个元素,您可以推断出该逻辑将导致第一个元素本身。 
所以,最后我们得到(number + string = string):
1
+
"0"
=== "10" // Yay! +[]规格详情: 
这是一个迷宫,但要做+[] ,首先它被转换为字符串,因为这就是+所说的: 
11.4.6 一元 + 算子
一元 + 运算符将其操作数转换为数字类型。
生产 UnaryExpression:+ UnaryExpression 的计算方法如下:
设 expr 是评估 UnaryExpression 的结果。
返回 ToNumber(GetValue(expr))。
 ToNumber()说: 
宾语
应用以下步骤:
设 primValue 为 ToPrimitive(输入参数,提示字符串)。
返回 ToString(primValue)。
 ToPrimitive()说: 
宾语
返回 Object 的默认值。通过调用对象的 [[DefaultValue]] 内部方法,传递可选提示 PreferredType 来检索对象的默认值。对于 8.12.8 中的所有本机 ECMAScript 对象,此规范定义了 [[DefaultValue]] 内部方法的行为。
 [[DefaultValue]]说: 
8.12.8 [[DefaultValue]](提示)
当使用提示字符串调用 O 的 [[DefaultValue]] 内部方法时,将执行以下步骤:
设 toString 是使用参数 “toString” 调用对象 O 的 [[Get]] 内部方法的结果。
如果 IsCallable(toString)为真,那么,
一个。令 str 为调用 toString 的 [[Call]] 内部方法的结果,其中 O 为此值,且为空参数列表。
湾如果 str 是原始值,则返回 str。
数组的.toString说: 
15.4.4.2 Array.prototype.toString()
调用 toString 方法时,将执行以下步骤:
令数组是在此值上调用 ToObject 的结果。
让 func 成为使用参数 “join” 调用数组的 [[Get]] 内部方法的结果。
如果 IsCallable(func)为 false,则让 func 成为标准的内置方法 Object.prototype.toString(15.2.4.2)。
返回调用 func 提供数组的 [[Call]] 内部方法的结果作为此值和空参数列表。
所以+[]归结为+"" ,因为[].join() === "" 。 
同样, +定义为: 
11.4.6 一元 + 算子
一元 + 运算符将其操作数转换为数字类型。
生产 UnaryExpression:+ UnaryExpression 的计算方法如下:
设 expr 是评估 UnaryExpression 的结果。
返回 ToNumber(GetValue(expr))。
 ToNumber的定义为""为: 
StringNumericLiteral ::: [empty] 的 MV 为 0。
所以+"" === 0 ,因此+[] === 0 。 
++[[]][+[]] => 1 // [+[]] = [0], ++0 = 1
[+[]] => [0]然后我们有一个字符串连接
1+[0].toString() = 10以下内容改编自一篇博客文章,回答了我在此问题仍未结束时发布的问题。链接是 ECMAScript 3 规范的(HTML 副本),仍然是当今常用 Web 浏览器中 JavaScript 的基线。
首先,评论:这种表达式永远不会出现在任何(理智的)生产环境中,并且只是作为一种练习用于读者如何知道 JavaScript 的脏边缘。 JavaScript 运算符在类型之间隐式转换的一般原则是有用的,一些常见的转换也是如此,但在这种情况下的大部分细节都不是。
表达式++[[]][+[]]+[+[]]最初可能看起来相当模糊和模糊,但实际上相对容易分解为单独的表达式。下面我简单地添加了括号以便清楚; 我可以向你保证他们什么都不会改变,但是如果你想验证那么你可以随意阅读有关分组操作员的信息 。因此,表达式可以更清楚地写成
( ++[[]][+[]] ) + ( [+[]] )打破这一点,我们可以通过观察+[]求值为0来简化。为了满足自己为什么这是真的,请查看一元 + 运算符并遵循稍微曲折的路径,最终使用ToPrimitive将空数组转换为空字符串,然后最终由ToNumber转换为0 。我们现在可以为+[]每个实例替换0 : 
( ++[[]][0] ) + [0]已经更简单了。对于++[[]][0] ,这是前缀增量运算符 ( ++ )的组合,一个数组文字定义一个数组,其中单个元素本身是一个空数组( [[]] )和一个属性访问器 ( [0] )调用数组文字定义的数组。 
那么,我们可以将[[]][0]简化为[] ,我们有++[] ,对吧?事实上,情况并非如此,因为评估++[]会引发错误,最初可能会让人感到困惑。然而,对++的本质的一点思考使得这一点变得清晰:它用于增加变量(例如++i )或对象属性(例如++obj.count )。它不仅评估值,还将值存储在某个地方。在++[]的情况下,它无处放置新值(无论它是什么),因为没有对要更新的对象属性或变量的引用。在规范方面,这由内部PutValue操作覆盖,该操作由前缀增量运算符调用。 
那么, ++[[]][0]做什么呢?那么,通过与+[]类似的逻辑,内部数组被转换为0并且该值递增1以给出最终值1 。外部数组中的属性0的值更新为1 ,整个表达式的计算结果为1 。 
这让我们失望了
1 + [0] ... 这是加法运算符的简单用法。两个操作数首先转换为基元 ,如果原始值是字符串,则执行字符串连接,否则执行数字加法。 [0]转换为"0" ,因此使用字符串连接,产生"10" 。 
作为最后的一点,可能不会立即显而易见的是,覆盖Array.prototype的toString()或valueOf()方法中的任何一个都将更改表达式的结果,因为在转换时,如果存在则两者都被检查和使用将对象转换为原始值。例如,以下内容
Array.prototype.toString = function() {
  return "foo";
};
++[[]][+[]]+[+[]] ...... 生产"NaNfoo" 。为什么会发生这种情况留给读者练习...