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

Ric*_*ick 17 javascript type-conversion

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

+[]; // 0
Number([]); // 0
Run Code Online (Sandbox Code Playgroud)

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

+{}; // NaN
Number({}); // NaN
Run Code Online (Sandbox Code Playgroud)

我一直在寻找这个有一段时间而没有任何成功......

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

这种行为是标准的吗?

谢谢.

CMS*_*CMS 23

简而言之,有两个关键点:

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

var obj = { toString: function () { return "";} };
+obj; //  0
Number(obj); // 0
Run Code Online (Sandbox Code Playgroud)

这种行为完全是标准的.

现在答案很长:

两者中,一元加运算符Number作为函数调用构造函数内部使用的ToNumber抽象操作.

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

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

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

ToPrimitive调用[[DefaultValue]]内部方法,也使用"数字"提示类型.

现在,由于提示类型我们使用"Number",[[DefaultValue]]现在内部方法将尝试首先调用valueOf该对象上的方法.

数组对象没有特定的valueOf方法,该方法是从中继承的方法Object.prototype.valueOf,而这个方法只返回对象本身的引用.

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

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

+""; // 0
Run Code Online (Sandbox Code Playgroud)

ToNumber内部操作应用于String类型(StringNumericLiteral生产)时,会使用完整的语法.

它在NumericLiteral之间存在一些差异,其中一个区别在于:

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

  • +1 Array实际上是JavaScript中的对象类型,因此它具有toString()方法. (2认同)