Javascript 对';瓦特';为CodeMash 2012演讲?

Javascript 对';瓦特';为CodeMash 2012演讲?,javascript,Javascript,基本上,本文指出了Ruby和JavaScript的一些奇怪之处 我已经在上做了一些结果 下面列出了特定于JavaScript的行为(我不知道Ruby) 我在JSFIDLE中发现我的一些结果与视频中的结果不一致,我不知道为什么。然而,我很想知道JavaScript在每种情况下是如何处理幕后工作的 Empty Array + Empty Array [] + [] result: <Empty String> 这与视频的结果相匹配。这是怎么回事?为什么这是一个物体。+操作员做什么 Ob

基本上,本文指出了Ruby和JavaScript的一些奇怪之处

我已经在上做了一些结果

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

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

Empty Array + Empty Array
[] + []
result:
<Empty String>
这与视频的结果相匹配。这是怎么回事?为什么这是一个物体。
+
操作员做什么

Object + Empty Array
{} + []
result:
[Object]
这与视频不匹配。视频显示结果为0,而我得到[Object]

Object + Object
{} + {}
result:
[Object][Object]
这与视频也不匹配,输出变量如何产生两个对象?也许我的JSFIDLE是错的

Array(16).join("wat" - 1)
result:
NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
执行wat+1会导致
wat1wat1wat1wat1wat1


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

以下是对您正在看到(以及应该看到)的结果的解释列表。我使用的参考资料来自

  • []+[]
    使用加法运算符时,左操作数和右操作数都将首先转换为基本体()。根据,将对象(在本例中为数组)转换为原语将返回其默认值,对于具有有效
    toString()
    方法的对象,该值是调用
    object.toString()
    ()的结果。对于数组,这与调用
    array.join()
    ()相同。连接一个空数组会产生一个空字符串,因此加法运算符的步骤#7返回两个空字符串的串联,即空字符串

  • []+{}
    []+[]
    类似,两个操作数都首先转换为原语。对于“对象对象”(§15.2),这也是调用
    对象.toString()
    的结果,对于非空、非未定义的对象,它是
    “[对象对象]”
    ()

  • {}+[]
    这里的
    {}
    不是作为一个对象来解析的,而是作为一个空块来解析的(至少只要您不强制该语句成为一个表达式,但稍后会详细介绍)。空块的返回值为空,因此该语句的结果与
    +[]
    相同。一元
    +
    运算符()返回
    ToNumber(ToPrimitive(操作数))
    。正如我们已经知道的,
    ToPrimitive([])
    是空字符串,根据,
    ToNumber(“”)
    是0

  • {}+{}
    与前一种情况类似,第一个
    {}
    被解析为返回值为空的块。同样,
    +{{code>与
    tonnumber(ToPrimitive({}))
    ,以及
    ToPrimitive({})
    “[object object]”
    (请参见
    [+{}{code>)。因此,为了得到
    +{}
    的结果,我们必须在字符串
    “[object object]”
    上应用
    ToNumber
    。按照中的步骤操作时,我们得到
    NaN
    ,结果是:

    如果语法无法将字符串解释为StringNumericLiteral的扩展,则结果为NaN

  • 数组(16)。加入(“wat”-1)
    根据和,
    Array(16)
    创建一个长度为16的新数组。要获取要联接的参数值,步骤5和步骤6显示,我们必须使用
    ToNumber
    将两个操作数转换为一个数字
    ToNumber(1)
    仅仅是1(),而
    ToNumber(“wat”)
    同样是
    NaN
    。按照的步骤7,指示

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

    因此
    Array(16.join)的参数是
    NaN
    。根据§15.4.4.5(
    Array.prototype.join
    ),我们必须调用参数
    ToString
    ,它是
    “NaN”
    ():

    如果m是NaN,则返回字符串
    “NaN”

    在的第10步之后,我们将重复15次将
    “NaN”
    和空字符串串联在一起,这等于您看到的结果。 当使用
    “wat”+1
    而不是
    “wat”-1
    作为参数时,加法运算符将
    1
    转换为字符串,而不是将
    “wat”
    转换为数字,因此它有效地调用
    数组(16)。join(“wat1”)


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

    以下是对您正在看到(以及应该看到)的结果的解释列表。我使用的参考资料来自

  • []+[]
    使用加法运算符时,左操作数和右操作数都将首先转换为基本体()。根据,将对象(在本例中为数组)转换为原语将返回其默认值,对于具有有效
    toString()
    方法的对象,该值是调用
    object.toString()
    ()的结果。对于数组,这与调用
    array.join()
    ()相同。连接一个空数组会产生一个空字符串,因此加法运算符的步骤#7返回两个空字符串的串联,即空字符串

  • []+{}
    []+[]
    类似,两个操作数都首先转换为原语。对于“对象对象”(§15.2),这也是调用
    对象.toString()
    的结果,对于非空、非未定义的对象,它是
    “[对象对象]”
    ()

  • {}+[]
    这里的
    {}
    不是作为对象解析的,而是作为空块(,至少作为l)解析的
    Array(16).join("wat" - 1)
    result:
    NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
    
    var obj = {
        valueOf: function () {
            console.log("valueOf");
            return {}; // not a primitive
        },
        toString: function () {
            console.log("toString");
            return {}; // not a primitive
        }
    }
    
    > Number(obj)
    valueOf
    toString
    TypeError: Cannot convert object to primitive value
    
    if (u)
        v;
    
    if (x) {
        y;
        z;
    }
    
    function out(code) {
        function format(x) {
            return typeof x === "string" ?
                JSON.stringify(x) : x;
        }   
        document.writeln('&gt;&gt;&gt; ' + code);
        document.writeln(format(eval(code)));
    }
    document.writeln("<pre>");
    out('[] + []');
    out('[] + {}');
    out('{} + []');
    out('{} + {}');
    out('Array(16).join("wat" + 1)');
    out('Array(16).join("wat - 1")');
    out('Array(16).join("wat" - 1) + " Batman!"');
    document.writeln("</pre>");
    
    +-----------------+-------------------+---------------+
    | Primitive Value |   String value    | Numeric value |
    +-----------------+-------------------+---------------+
    | null            | “null”            | 0             |
    | undefined       | “undefined”       | NaN           |
    | true            | “true”            | 1             |
    | false           | “false”           | 0             |
    | 123             | “123”             | 123           |
    | []              | “”                | 0             |
    | {}              | “[object Object]” | NaN           |
    +-----------------+-------------------+---------------+