有人可以向我解释为什么会出现这些结果吗?
我知道这不是一个真正的问题,但我很想知道。
由于
答案 0 :(得分:11)
这是因为+
用于添加数字和字符串,它也是unary operator。这也是因为{}
既是空对象又是block statement。
我可以解释一下。
[] + {}
两者都转换为字符串。
[].toString() + {}.toString()
[].toString()
与[].join('')
相同,{}.toString()
为'[object Object]'
,因此第一个是[object Object]
。
第二个更令人困惑。
{} + []
此处的{}
不被解释为对象,被解释为空块。所以里面的代码是运行的。内部没有任何内容,因此它什么都不做,然后下一个语句运行:+[]
。这会将数组转换为int,然后首先将其转换为字符串而不是字符串。
{} + [] => +[] => +([].toString()) => 0
如果将{}
放在括号中,它将与第一个相同。
({}) + [] => '[object Object]'
答案 1 :(得分:6)
[] + []
使用加法运算符时,左右操作数首先转换为基元(§11.6.1)。根据{{3}}, 将对象(在本例中为数组)转换为基元返回 它的默认值,对于具有有效
toString()
方法的对象 是调用object.toString()
(§9.1)的结果。对于 数组与调用array.join()
([§15.4.4.2] [4])相同。 连接一个空数组会产生一个空字符串,所以步骤#7 加法运算符返回两个空字符串的串联, 这是空字符串。
[] + {}
与
[] + []
类似,两个操作数首先转换为基元。对于“对象对象”(第15.2节),这又是结果 调用object.toString()
,用于非null,未定义的对象 是"[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],[§11.6.3] [17]的第7步 决定如果任一操作数为 NaN ,则结果为 NaN 。
所以
Array(16).join
的论点是NaN
。遵循§15.4.4.5(Array.prototype.join
),我们必须在论证上调用ToString
, 这是"NaN"
([§9.8.1] [18]):如果 m NaN ,请返回字符串
"NaN"
。在[§15.4.4.5] [19]的第10步之后,我们得到了
"NaN"
和空字符串连接的15次重复,这等于结果 你看到了。使用"wat" + 1
代替"wat" - 1
时 参数,加法运算符将1
转换为字符串而不是 将"wat"
转换为数字,以便有效地调用Array(16).join("wat1")
。