就在我以为自己对JavaScript中的类型转换有所了解时,我遇到了这个问题:
+[]; // 0
Number([]); // 0
我的第一反应是会得到NaN,就像把一个空对象转换成数字时一样:
+{}; // NaN
Number({}); // NaN
我已经搜索了一段时间,但没有任何成功...
有人能解释一下为什么它会被转换为0而不是NaN吗?
这种行为是否标准?
谢谢。
就在我以为自己对JavaScript中的类型转换有所了解时,我遇到了这个问题:
+[]; // 0
Number([]); // 0
我的第一反应是会得到NaN,就像把一个空对象转换成数字时一样:
+{}; // NaN
Number({}); // NaN
我已经搜索了一段时间,但没有任何成功...
有人能解释一下为什么它会被转换为0而不是NaN吗?
这种行为是否标准?
谢谢。
toString
方法返回一个空字符串。Number
构造函数作为函数调用(例如:+"" === 0;
)来强制转换为零。toString
方法并返回一个空字符串的对象来获得相同的结果:var obj = { toString: function () { return "";} };
+obj; // 0
Number(obj); // 0
Number
构造函数作为函数调用,内部都使用了ToNumber
抽象操作。
ToNumber
将使用另外两个内部操作,ToPrimitive
和[[DefaultValue]]
。ToNumber
操作时,例如你的示例中的空数组,它会调用ToPrimitive
操作,以获取一个代表性的原始值,并再次使用该值调用ToNumber
[1]。
ToPrimitive
操作接收两个参数,一个是值(即你的数组对象),另一个是提示类型,在这种情况下是"Number",因为我们想进行数值转换。
ToPrimitive
调用[[DefaultValue]]
内部方法,同样使用"Number"提示类型。[[DefaultValue]]
内部方法将首先尝试调用对象上的valueOf
方法。valueOf
方法,该方法是从Object.prototype.valueOf
继承而来,该方法只是简单地返回对对象本身的引用。
由于valueOf
方法未产生一个原始值,现在调用toString
方法,它生成一个空字符串(这是一个原始值),然后ToNumber
操作将尝试进行字符串到数字的转换,最终得到0
[1]。
但是现在你可能会想,为什么一个空字符串强制转换成零?
+""; // 0
当将ToNumber
内部操作应用于String类型时,有一个完整的语法,即StringNumericLiteral
产生式。
它与NumericLiteral之间有一些差异,其中之一是:
一个空的或只包含空格的StringNumericLiteral会被转换为+0。