对于CodeMash 2012的“Wat”演讲中提到的这些奇怪的JavaScript行为有什么解释? [英] What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?

查看:148
本文介绍了对于CodeMash 2012的“Wat”演讲中提到的这些奇怪的JavaScript行为有什么解释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The 'Wat' talk for CodeMash 2012 basically points out a few bizarre quirks with Ruby and JavaScript.

我已经在 http:/上创建了一个结果的JSFiddle /jsfiddle.net/fe479/9/

下面列出了JavaScript特有的行为(我不知道Ruby)。

The behaviours specific to JavaScript (as I don't know Ruby) are listed below.

我在JSFiddle中发现我的一些结果与视频中的结果不符,我不知道为什么。但是,我很想知道JavaScript在每种情况下如何处理幕后工作。

I found in the JSFiddle that some of my results didn't correspond with those in the video, and I am not sure why. I am, however, curious to know how JavaScript is handling working behind the scenes in each case.

Empty Array + Empty Array
[] + []
result:
<Empty String>

我对 + 运算符非常好奇在JavaScript中与数组一起使用时。
这匹配视频的结果。

I am quite curious about the + operator when used with arrays in JavaScript. This matches the video's result.

Empty Array + Object
[] + {}
result:
[Object]

这与视频的结果相符。这里发生了什么?为什么这是一个对象。 + 运算符有什么作用?

This matches the video's result. What's going on here? Why is this an object. What does the + operator do?

Object + Empty Array
{} + []
result
[Object]

这不是与视频不匹配。视频显示结果为0,而我得到[对象]。

This doesn't match the video. The video suggests that the result is 0, whereas I get [Object].

Object + Object
{} + {}
result:
[Object][Object]

这不是' t匹配视频,以及如何输出变量导致两个对象?也许我的JSFiddle错了。

This doesn't match the video either, and how does outputting a variable result in two objects? Maybe my JSFiddle is wrong.

Array(16).join("wat" - 1)
result:
NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

否则在 wat1wat1wat1wat1 ...

我怀疑这只是一种直截了当的行为,试图从字符串中减去一个数字会导致NaN。

I suspect this is just straightforward behaviour that trying to subtract a number from a string results in NaN.

推荐答案

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

Here's a list of explanations for the results you're seeing (and supposed to be seeing). The references I'm using are from the ECMA-262 standard.


  1. [] + []



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

  1. [] + []

    When using the addition operator, both the left and right operands are converted to primitives first (§11.6.1). As per §9.1, converting an object (in this case an array) to a primitive returns its default value, which for objects with a valid toString() method is the result of calling object.toString() (§8.12.8). For arrays this is the same as calling array.join() (§15.4.4.2). Joining an empty array results in an empty string, so step #7 of the addition operator returns the concatenation of two empty strings, which is the empty string.

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

Similar to [] + [], both operands are converted to primitives first. For "Object objects" (§15.2), this is again the result of calling object.toString(), which for non-null, non-undefined objects is "[object Object]" (§15.2.4.2).

{} 此处未被解析为对象,而是作为空块解析(§12.1,至少只要您不强制该语句为表达式,但稍后会详细说明。空块的返回值为空,因此该语句的结果与 + [] 相同。一元 + 运算符(§ 11.4.6 )返回 ToNumber(ToPrimitive(操作数))。我们已经知道, ToPrimitive([])是空字符串,根据§9.3.1 ToNumber()为0。

The {} here is not parsed as an object, but instead as an empty block (§12.1, at least as long as you're not forcing that statement to be an expression, but more about that later). The return value of empty blocks is empty, so the result of that statement is the same as +[]. The unary + operator (§11.4.6) returns ToNumber(ToPrimitive(operand)). As we already know, ToPrimitive([]) is the empty string, and according to §9.3.1, ToNumber("") is 0.

与之前的案例类似,第一个 {} 被解析为具有空返回值的块。同样, + {} ToNumber(ToPrimitive({}))相同,并且 ToPrimitive({})[object Object](参见 [] + {} )。因此,要获得 + {} 的结果,我们必须在字符串上应用 ToNumber [object Object]。按照§9.3.1中的步骤操作时,我们得到 NaN 结果:

Similar to the previous case, the first {} is parsed as a block with empty return value. Again, +{} is the same as ToNumber(ToPrimitive({})), and ToPrimitive({}) is "[object Object]" (see [] + {}). So to get the result of +{}, we have to apply ToNumber on the string "[object Object]". When following the steps from §9.3.1, we get NaN as a result:


如果语法不能将String解释为 StringNumericLiteral ,那么 ToNumber 的结果是 NaN


  • 数组(16).join(wat - 1)



    根据§15.4.1.1§15.4.2.2 Array(16)创建一个长度为16的新数组。要获取要加入的参数的值,§11.6.2步骤#5和#6表明我们必须使用<$ c $将两个操作数转换为数字C> ToNumber ToNumber(1)只是1( §9.3),而 ToNumber(wat)再次 NaN ,按§9.3.1。按照§11.6.2的第7步,§11.6.3规定

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

    As per §15.4.1.1 and §15.4.2.2, Array(16) creates a new array with length 16. To get the value of the argument to join, §11.6.2 steps #5 and #6 show that we have to convert both operands to a number using ToNumber. ToNumber(1) is simply 1 (§9.3), whereas ToNumber("wat") again is NaN as per §9.3.1. Following step 7 of §11.6.2, §11.6.3 dictates that


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

    因此 Array(16).join 的参数是 NaN 。遵循§15.4.4.5( Array.prototype.join ),我们必须在参数上调用 ToString ,这是NaN§9.8 .1 ):

    So the argument to Array(16).join is NaN. Following §15.4.4.5 (Array.prototype.join), we have to call ToString on the argument, which is "NaN" (§9.8.1):


    如果 m NaN ,则返回字符串 NaN

    If m is NaN, return the String "NaN".

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

    Following step 10 of §15.4.4.5, we get 15 repetitions of the concatenation of "NaN" and the empty string, which equals the result you're seeing. When using "wat" + 1 instead of "wat" - 1 as argument, the addition operator converts 1 to a string instead of converting "wat" to a number, so it effectively calls Array(16).join("wat1").

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

    As to why you're seeing different results for the {} + [] case: When using it as a function argument, you're forcing the statement to be an ExpressionStatement, which makes it impossible to parse {} as empty block, so it's instead parsed as an empty object literal.

    这篇关于对于CodeMash 2012的“Wat”演讲中提到的这些奇怪的JavaScript行为有什么解释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆