下面列出了特定于JavaScript的行为(因为我不了解Ruby)。
我在JSFiddle中发现我的某些结果与视频中的结果不符,我不确定为什么。但是,我很想知道JavaScript在每种情况下如何处理幕后工作。
Empty Array + Empty Array [] + [] result: <Empty String>
+当与JavaScript中的数组一起使用时,我对运算符非常好奇。这与视频结果匹配。
+
Empty Array + Object [] + {} result: [Object]
这与视频结果匹配。这里发生了什么?为什么这是一个对象。什么是+运营商吗?
Object + Empty Array {} + [] result [Object]
这与视频不匹配。视频表明结果为0,而我得到了[Object]。
Object + Object {} + {} result: [Object][Object]
这也不匹配视频,输出变量如何导致两个对象?也许我的JSFiddle是错的。
Array(16).join("wat" - 1) result: NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
做wat + 1会导致wat1wat1wat1wat1…
wat1wat1wat1wat1
我怀疑这是直接的行为,即试图从字符串中减去数字会导致NaN。
以下是对您所看到的结果的解释列表。我使用的参考资料来自ECMA-262标准。
[] + []
使用加法运算符时,左操作数和右操作数都首先转换为基元(第11.6.1节)。按照§9.1的规定,将对象(在这种情况下为数组)转换为基元将返回其默认值,对于具有有效toString()方法的对象,这是调用的结果object.toString()(第8.12.8节)。对于数组,这与调用array.join()(§15.4.4.2)相同。连接一个空数组会导致一个空字符串,因此加法运算符的第7步将返回两个空字符串的串联,即空字符串。
toString()
object.toString()
array.join()
[] + {}
与相似[] + [],两个操作数都首先转换为基元。对于“对象对象”(第15.2节),这再次是调用的结果object.toString(),对于非空,非未定义的对象,调用是"[object Object]"(第15.2.4.2节)。
"[object Object]"
{} + []
在{}这里不会被解析为一个对象,而是作为一个空块(§12.1,至少只要你不逼这种说法是一种表达,但稍后详细说明)。空块的返回值为空,因此该语句的结果与相同+[]。一元运算+符(第[11.4.6节)返回ToNumber(ToPrimitive(operand))。众所周知,ToPrimitive([])是空字符串,根据9.3.1节,ToNumber("")为0。
{}
+[]
ToNumber(ToPrimitive(operand))
ToPrimitive([])
ToNumber("")
{} + {}
与前一种情况类似,第一种情况{}被解析为具有空返回值的块。同样,+{}和相同ToNumber(ToPrimitive({})),并且ToPrimitive({})是"[objectObject]"(请参阅[] + {})。因此,要获得结果+{},我们必须ToNumber在字符串上应用"[object Object]"。按照[§9.3.1的步骤进行[操作时,NaN结果是:
+{}
ToNumber(ToPrimitive({}))
ToPrimitive({})
"[objectObject]"
ToNumber
NaN
如果语法无法将String解释为 StringNumericLiteral 的扩展,则ToNumber的结果为 NaN 。
Array(16).join("wat" - 1)
根据§15.4.1.1和§15.4.2.2,Array(16)创建一个长度为16的新数组。要获取要连接的参数的值,§11.6.2步骤#5和#6显示我们必须将两个操作数都转换为a。使用编号ToNumber。ToNumber(1)仅仅是1第9.3节],而ToNumber("wat")再次NaN按§9.3.1。下面的步骤7§11.6.2,[§11.6.3]决定了
Array(16)
ToNumber(1)
ToNumber("wat")
如果任一操作数为 NaN ,则结果为 NaN 。
因此,的论据Array(16).join是NaN。在§15.4.4.5(Array.prototype.join)之后,我们必须调用ToString参数"NaN"(§9.8.1):
Array(16).join
Array.prototype.join
ToString
"NaN"
如果 m 为 NaN ,则返回String "NaN" 。
在§15.4.4.5的步骤10之后,我们得到了15个重复的串联连接"NaN"和空字符串,这等于您看到的结果。当使用"wat" + 1代替"wat" - 1作为参数时,加法运算符将转换1为字符串而不是"wat"数字,因此它有效地调用Array(16).join("wat1")。
"wat" + 1
"wat" - 1
1
"wat"
Array(16).join("wat1")
关于为什么看到这种{} + []情况的不同结果:当将其用作函数参数时,您将强制该语句为 ExpressionStatement ,这使得无法将其解析{}为空块,因此将其解析为空对象文字。