CodeMash 2012的“Wat”演讲基本上指出了Ruby和JavaScript的一些奇怪之处
我在上一次会议上对结果作了简要介绍http://jsfiddle.net/fe479/9/.
下面列出了特定于JavaScript的行为(我不知道Ruby)
我在JSFIDLE中发现我的一些结果与视频中的结果不一致,我不知道为什么。然而,我很想知道JavaScript在每种情况下是如何处理幕后工作的
空数组+空数组
[] + []
结果:
<;空字符串>;
在JavaScript中与数组一起使用时,我对+操作符非常好奇。
这与视频的结果相匹配
空数组+对象
[] + {}
结果:
[对象]
这与视频的结果相匹配。这是怎么回事?为什么这是一个物体。+操作员做什么
对象+空数组
{} + []
结果:
[对象]
这与视频不匹配。视频显示结果为0,而我得到[Object]
对象+对象
{} + {}
结果:
[实物][实物]
这与视频也不匹配,输出变量如何产生两个对象?也许我的JSFIDLE是错的
数组(16).连接(“wat”-1)
结果:
南南南南
执行wat+1会导致wat1wat1wat1wat1wat1
我怀疑这只是简单的行为,试图从字符串中减去一个数字会导致NaN
下面是一个列表,说明了您正在看到(以及应该看到)的结果。我使用的参考来自ECMA-262标准
-
[]+[]使用加法运算符时,左操作数和右操作数都将首先转换为基元(§11.6.1)。根据§9.1,将对象(在本例中为数组)转换为原语将返回其默认值,对于具有有效
toString()方法的对象,该值是调用object.toString()(§8.12.8)的结果。对于数组,这与调用array.join()(§15.4.4.2)相同。连接一个空数组会产生一个空字符串,因此加法运算符的步骤#7返回两个空字符串的串联,即空字符串 -
[]+{}与
[]+[]类似,两个操作数都首先转换为原语。对于“对象对象”(§15.2),这也是调用对象.toString()的结果,对于非空、非未定义的对象是“[对象对象]”(§15.2.4.2) -
{}+[]这里的
{}不是作为对象解析的,而是作为一个空块解析的(§12.1,至少只要您不强制该语句成为表达式,但稍后会详细介绍)。空块的返回值为空,因此该语句的结果与+[]相同。一元+运算符(§11.4.6)返回ToNumber(ToPrimitive(operand))。我们已经知道,ToPrimitive([])是空字符串,根据§9.3.1,ToNumber(“”)是0 -
{}+{}与前一种情况类似,第一个
{}被解析为返回值为空的块。同样,+{}与ToNumber(ToPrimitive({}))相同,ToPrimitive({})是“[对象对象]”(请参见[]+{})。因此,为了得到+{}的结果,我们必须在字符串“[object object]”上应用ToNumber。当按照§9.3.1中的步骤进行操作时,我们得到NaN:如果语法无法将字符串解释为StringNumericLiteral的扩展,则ToNumber的结果为NaN
-
数组(16)。加入(“wat”-1)根据§15.4.1.1和§15.4.2.2,
数组(16)创建长度为16的新数组。为了获得要联接的参数值,§11.6.2步骤5和步骤6显示,我们必须使用ToNumber将两个操作数转换为一个数字ToNumber(1)仅为1(§9.3),而ToNumber(“wat”)根据§9.3.1再次为NaN。根据§11.6.2第7步,§11.6.3规定:如果任一操作数为NaN,则结果为NaN
因此
Array(16.join)的参数是NaN。在§15.4.4.5(Array.prototype.join)之后,我们必须调用ToString,参数为“NaN”(§9.8.1):如果m是NaN,则返回字符串
“NaN”在§15.4.4.5的步骤10之后,我们得到了15次重复的
“NaN”和空字符串的串联,这等于您看到的结果。
当使用“wat”+1而不是“wat”-1作为参数时,加法运算符将1转换为字符串,而不是将“wat”转换为数字,因此它有效地调用数组(16)。join(“wat1”)
至于为什么在{}+[]案例中会看到不同的结果:当将它用作函数参数时,您强制语句成为表达式语句,这使得不可能将{}解析为空块,因此它被解析为空对象文本