11

有人可以向我解释为什么会出现这些结果吗?

在此处输入图像描述

我知道这不是一个真正的问题,但我很想知道。

谢谢

4

2 回答 2

11

+是因为用于添加数字和字符串,它也是一元运算符。这也是因为{}既是空对象又是块语句

我可以解释这一点。

[] + {}

两者都转换为字符串。

[].toString() + {}.toString()

[].toString()和 一样[].join(''),{}.toString()'[object Object]', 所以第一个是[object Object].

第二个更混乱。

{} + []

这里{}被解释为一个对象,被解释为一个空块。于是里面的代码就跑起来了。里面什么都没有,所以什么都不做,然后运行下一条语句 :这会将数组转换为 int,它首先将其转换为字符串而不是 it。+[]

{} + [] => +[] => +([].toString()) => 0

如果你把括号放在{}括号里,它会和第一个一样。

({}) + [] => '[object Object]'
于 2013-06-20T18:11:37.570 回答
6

这里开始,与此有关

  1. [] + []

    使用加法运算符时,左操作数和右操作数都首先转换为基元(第11.6.1 节)。根据第 9.1 节,将对象(在本例中为数组)转换为原语会返回其默认值,对于具有有效toString()方法的对象,该值是调用的结果object.toString()第 8.12.8 节)。对于数组,这与调用array.join()([§15.4.4.2][4]) 相同。连接一个空数组会产生一个空字符串,所以加法运算符的第 7 步返回两个空字符串的连接,也就是空字符串。

  2. [] + {}

    与 类似[] + [],两个操作数都首先转换为基元。对于“对象对象”(第 15.2 节),这又是调用 的结果object.toString(),对于非空、非未定义的对象是"[object Object]"([§15.2.4.2][5])。

  3. {} + []

    这里{}不被解析为一个对象,而是一个空块([§12.1][6],至少只要你不强迫该语句成为一个表达式,但稍后会详细介绍)。空块的返回值为空,因此该语句的结果与+[]. 一元运算+符 ([§11.4.6][7]) 返回 ToNumber(ToPrimitive(operand)). 正如我们已经知道的, ToPrimitive([])是空字符串,根据[§9.3.1][8], ToNumber("")是 0。

  4. {} + {}

    与前一种情况类似,第一种{}被解析为返回值为空的块。同样,+{}与 相同 ToNumber(ToPrimitive({})),并且ToPrimitive({})"[object Object]"(参见[] + {})。所以要得到 的结果+{},我们必须ToNumber在字符串上应用"[object Object]"。当按照 [§9.3.1][9] 中的步骤进行操作时,我们得到NaN

    如果语法无法将 String 解释为StringNumericLiteral的扩展,则 [ToNumber][10] 的结果为NaN

  5. Array(16).join("wat" - 1)

    根据 [§15.4.1.1][11] 和 [§15.4.2.2][12],Array(16)创建一个长度为 16 的新数组。要获取要加入的参数的值,[§11.6.2][13] 步骤#5 和 #6 表明我们必须使用 . 将两个操作数转换为数字ToNumberToNumber(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).joinNaN。在 §15.4.4.5 ( Array.prototype.join) 之后,我们必须调用ToString参数,即"NaN"([§9.8.1][18]):

    如果mNaN,则返回 String "NaN"

    在 [§15.4.4.5][19] 的第 10 步之后,我们得到 15 次重复的连接"NaN"和空字符串,这等于您看到的结果。当使用"wat" + 1而不是"wat" - 1作为参数时,加法运算符转换1为字符串而不是转换"wat"为数字,因此它有效地调用 Array(16).join("wat1").

于 2013-06-20T18:12:59.237 回答