为啥空数组类型转换为零? +[]

Posted

技术标签:

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

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

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

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

+; // NaN
Number(); // NaN

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

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

这种行为标准吗?

谢谢。

【问题讨论】:

【参考方案1】:

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

空数组的toString方法返回一个空字符串。 使用unary plus operator 或Number constructor called as a function(例如+"" === 0;)将一个空字符串强制归零。

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

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

这种行为是完全标准的。

现在是长答案:

unary plus operator 和Number 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 type、StringNumericLiteral 产生式时使用了完整的语法。

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

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

【讨论】:

+1 Array实际上是JavaScript中的对象类型,所以它有一个toString()方法。 为什么 Array 对象没有 valueOf 方法?

以上是关于为啥空数组类型转换为零? +[]的主要内容,如果未能解决你的问题,请参考以下文章

为啥numpy数组的astype方法在转换类型时不修改输入?

为啥在使用单指针传递给函数时必须对二维数组进行类型转换?

在for循环中将PFFile数组转换为UIImage返回空数组Swift

js 如何判断数组为空

为啥 Swift4 会强制转换 UIButton 数组!到 [UIButton?] 类型?

为啥我的 C# 数组在转换为对象时会丢失类型符号信息?