【问题标题】:Why an empty Array type-converts to zero? +[]为什么空数组类型转换为零? +[]
【发布时间】:2011-03-19 09:35:18
【问题描述】:

就在我以为我对 JavaScript 中的类型转换有所了解时,我偶然发现了这个:

+[]; // 0
Number([]); // 0

我的第一个想法是我应该得到 NaN,就像我尝试将空对象转换为数字一样:

+{}; // NaN
Number({}); // NaN

我已经搜索了一段时间没有任何成功......

有人能解释一下为什么它被转换为 0 而不是 NaN 吗?

这种行为标准吗?

谢谢。

【问题讨论】:

    标签: javascript type-conversion


    【解决方案1】:

    简单来说,有两个关键点:

    例如,我们可以使用一个对象,它定义了一个toString方法,并返回一个空字符串得到一个等价的结果:

    var obj = { toString: function () { return "";} };
    +obj; //  0
    Number(obj); // 0
    

    这种行为是完全标准的。

    现在是长答案:

    unary plus operatorNumber constructor called as a function 在内部都使用ToNumber 抽象操作。

    ToNumber 将使用另外两个内部操作,ToPrimitive[[DefaultValue]]

    ToNumber 操作应用于对象时,例如您的示例中的空数组,它调用ToPrimitive 操作,以获取具有代表性的原始值并使用该值再次调用ToNumber [ 1].

    ToPrimitive 操作接收两个参数,一个值(这是您的数组对象)和一个提示类型,在本例中为“数字”,因为我们要进行数字转换。

    ToPrimitive 调用[[DefaultValue]] 内部方法,同样带有“数字”提示类型。

    现在,由于我们使用“数字”的提示类型,[[DefaultValue]] 内部方法现在将尝试首先调用对象上的 valueOf 方法。

    数组对象没有特定的valueOf方法,该方法是继承自Object.prototype.valueOf的方法,并且该方法只是返回对对象本身的引用。

    由于valueOf 方法没有产生原始值,现在调用toString 方法,它产生一个空字符串(这是一个原始值),然后ToNumber 操作将尝试进行字符串-数字转换,最终以0 [1]结束。

    但现在您可能想知道,为什么一个空字符串会强制为零?

    +""; // 0
    

    ToNumber internal operation is applied to a String typeStringNumericLiteral 产生式时使用了完整的语法。

    NumericLiteral 之间存在一些差异,其中一个差异是:

    为空或仅包含空格的 StringNumericLiteral 将转换为 +0。

    【讨论】:

    • +1 Array实际上是JavaScript中的对象类型,所以它有一个toString()方法。
    • 为什么 Array 对象没有 valueOf 方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 2021-12-07
    • 2014-12-30
    • 2013-05-01
    相关资源
    最近更新 更多