有人可以向我解释为什么会出现这些结果吗?
我知道这不是一个真正的问题,但我很想知道。
谢谢
这+
是因为用于添加数字和字符串,它也是一元运算符。这也是因为{}
既是空对象又是块语句。
我可以解释这一点。
[] + {}
两者都转换为字符串。
[].toString() + {}.toString()
[].toString()
和 一样[].join('')
,{}.toString()
是'[object Object]'
, 所以第一个是[object Object]
.
第二个更混乱。
{} + []
这里不{}
被解释为一个对象,被解释为一个空块。于是里面的代码就跑起来了。里面什么都没有,所以什么都不做,然后运行下一条语句 :这会将数组转换为 int,它首先将其转换为字符串而不是 it。+[]
{} + [] => +[] => +([].toString()) => 0
如果你把括号放在{}
括号里,它会和第一个一样。
({}) + [] => '[object Object]'
[] + []
使用加法运算符时,左操作数和右操作数都首先转换为基元(第11.6.1 节)。根据第 9.1 节,将对象(在本例中为数组)转换为原语会返回其默认值,对于具有有效
toString()
方法的对象,该值是调用的结果object.toString()
(第 8.12.8 节)。对于数组,这与调用array.join()
([§15.4.4.2][4]) 相同。连接一个空数组会产生一个空字符串,所以加法运算符的第 7 步返回两个空字符串的连接,也就是空字符串。
[] + {}
与 类似
[] + []
,两个操作数都首先转换为基元。对于“对象对象”(第 15.2 节),这又是调用 的结果object.toString()
,对于非空、非未定义的对象是"[object Object]"
([§15.2.4.2][5])。
{} + []
这里
{}
不被解析为一个对象,而是一个空块([§12.1][6],至少只要你不强迫该语句成为一个表达式,但稍后会详细介绍)。空块的返回值为空,因此该语句的结果与+[]
. 一元运算+
符 ([§11.4.6][7]) 返回ToNumber(ToPrimitive(operand))
. 正如我们已经知道的,ToPrimitive([])
是空字符串,根据[§9.3.1][8],ToNumber("")
是 0。
{} + {}
与前一种情况类似,第一种
{}
被解析为返回值为空的块。同样,+{}
与 相同ToNumber(ToPrimitive({}))
,并且ToPrimitive({})
是"[object Object]"
(参见[] + {}
)。所以要得到 的结果+{}
,我们必须ToNumber
在字符串上应用"[object Object]"
。当按照 [§9.3.1][9] 中的步骤进行操作时,我们得到NaN
:如果语法无法将 String 解释为StringNumericLiteral的扩展,则 [ToNumber][10] 的结果为NaN。
Array(16).join("wat" - 1)
根据 [§15.4.1.1][11] 和 [§15.4.2.2][12],
Array(16)
创建一个长度为 16 的新数组。要获取要加入的参数的值,[§11.6.2][13] 步骤#5 和 #6 表明我们必须使用 . 将两个操作数转换为数字ToNumber
。ToNumber(1)
只是 1 ([§9.3][14]),而ToNumber("wat")
同样是NaN
根据 [§9.3.1][15]。按照 [§11.6.2][16] 的第 7 步,[§11.6.3][17] 规定如果任一操作数为NaN,则结果为NaN。
所以 的论点
Array(16).join
是NaN
。在 §15.4.4.5 (Array.prototype.join
) 之后,我们必须调用ToString
参数,即"NaN"
([§9.8.1][18]):如果m是NaN,则返回 String
"NaN"
。在 [§15.4.4.5][19] 的第 10 步之后,我们得到 15 次重复的连接
"NaN"
和空字符串,这等于您看到的结果。当使用"wat" + 1
而不是"wat" - 1
作为参数时,加法运算符转换1
为字符串而不是转换"wat"
为数字,因此它有效地调用Array(16).join("wat1")
.