为什么 JavaScript 允许您将具有单个数值的数组乘以另一个数值或乘以具有单个数值的另一个数组?:
[3] * 3;
// 9
[3] * 2;
// 6
[3] * [3];
// 9
[1, 2] * 2
// NaN
我希望NaN
每次都能返回,但正如我在 Chrome 中的实验所证明的那样,情况并非如此。
这是预期的行为吗?这种行为有意义吗?如果是这样,为什么?
为什么 JavaScript 允许您将具有单个数值的数组乘以另一个数值或乘以具有单个数值的另一个数组?:
[3] * 3;
// 9
[3] * 2;
// 6
[3] * [3];
// 9
[1, 2] * 2
// NaN
我希望NaN
每次都能返回,但正如我在 Chrome 中的实验所证明的那样,情况并非如此。
这是预期的行为吗?这种行为有意义吗?如果是这样,为什么?
[3] * 3;
采取以下步骤:
[3] => "3"
Number("3") => 3
3 * 3
给9
同样,对于[1, 2] * 2
:
[1, 2] => ""1,2"
Number("1,2") => NaN
NaN * 3
给NaN
对于我们中间的 ECMA 怪胎;)从这里开始并遵循路径multiplicative operator => ToNumber => ToPrimitive => [[DefaultValue]](number) => valueOf => toString
这里发生的事情[3]
是被强制转换为一种String
类型,即"3"
. 然后"3" * 3
将String
值"3"
转换为数字3
。您最终得到3 * 3
,其计算结果为9
。
如果你这样做,你可以看到这种行为,[3].toString() * 3
或者"3" * 3
,这也给你9
,
所以会发生以下步骤:
[3] * 3
[3].toString() * 3
"3" * 3
Number("3") * 3
3 * 3
9
在这种情况下[1, 2]
,你最终以"1, 2"
. 但Number("1, 2")
结果是 aNaN
和一个数字乘以 aNaN
结果是NaN
。
http://ecma-international.org/ecma-262/5.1/#sec-15.4.4.2
由于 Array.prototype.valueOf 不可用,它回退到使用 String 版本(根据http://ecma-international.org/ecma-262/5.1/#sec-9.9)
toString 呈现一个具有单个元素的数组作为元素的值(因此 [3].toString() 为 3)