小编典典

CodeMash 2012 的“Wat”演讲中提到的这些奇怪的 JavaScript 行为的解释是什么?

all

CodeMash 2012 的“Wat”演讲基本上指出了Ruby 和 JavaScript 的一些奇怪的怪癖。

我在http://jsfiddle.net/fe479/9/上做了一个 JSFiddle的结果。

下面列出了特定于 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

我怀疑这只是尝试从字符串中减去数字导致 NaN 的简单行为。


阅读 106

收藏
2022-03-02

共1个答案

小编典典

这是您所看到(并且应该看到)结果的解释列表。我使用的参考来自ECMA-262 标准

  1. [] + []

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

  1. [] + {}

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

  1. {} + []

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

  1. {} + {}

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

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

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

根据搂15.4.1.1搂15.4.2.2创建Array(16)一个长度为16
的新数组。要获得要加入的参数的值,搂11.6.2步骤#5 和#6
表明我们必须将两个操作数转换为号码使用ToNumberToNumber(1)只是 1 (搂9.3
),而ToNumber("wat")再次是NaN搂9.3.1在拥抱 11.6.2的步骤 7 之后,拥抱
11.6.3
规定

如果任一操作数为 NaN ,则结果为 NaN

所以 的论点Array(16).joinNaN。继搂15.4.4.5(
Array.prototype.join)之后,我们要调用ToString论据,即"NaN"(搂9.8.1 ):

如果 mNaN ,则返回 String "NaN"

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

至于为什么您会看到不同的{} + []案例结果:当将其用作函数参数时,您将语句强制为 ExpressionStatement
,这使得无法解析{}为空块,因此将其解析为空对象文字。

2022-03-02