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

时间:2010-07-22 06:54:31

标签: javascript type-conversion

当我以为我理解了JavaScript中的类型转换时,我偶然发现了这个:

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

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

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

我一直在搜索这个问题一段时间没有任何成功......

有人可以解释为什么它会转换为0而不是NaN吗?

这种行为是标准的吗?

感谢。

1 个答案:

答案 0 :(得分:22)

简而言之,有两个要点:

例如,我们可以使用定义toString方法的对象,并返回一个空字符串以获得相同的结果:

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

此行为完全符合标准。

现在答案很长:

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

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

ToNumber操作应用于Object(例如示例中的空数组)时,它会调用ToPrimitive操作,以获取代表性原始值并再次使用ToNumber调用该值 [1]

ToPrimitive操作接收两个参数,一个Value(这是你的数组对象)和一个提示类型,在这种情况下是“Number”,因为我们想进行数字转换。

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。