用一个数字乘以数组中的单个数值?

7
为什么JavaScript允许你用单个数字值的另一个数字值或另一个单个数字值的数组来乘以数组?
[3] * 3;
// 9

[3] * 2;
// 6

[3] * [3];
// 9

[1, 2] * 2
// NaN

我原本期望每次都会返回NaN,但在我在Chrome浏览器中的实验表明这并非如此。这是否是预期行为?这种行为是否合理?如果是,为什么?

2
我认为http://www.youtube.com/watch?v=kXEgk1Hdze0是这里唯一可能的答案 :) - Ju Liu
4个回答

10
[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 Freaks ;) 可以从这里开始,然后按照路径multiplicative operator => ToNumber => ToPrimitive => [[DefaultValue]](number) => valueOf => toString进行。

现在完全明白了。在我注意到这种行为的_.clone方法的上下文中,它似乎是不希望的(也许不是,我还没有决定):_.clone([1, 2, [3]], function(num) { return num * 2; }),其中一个回调函数被应用于每个值,所以返回的结果是[2, 4, 6]。...我不想与我使用的语言对抗,但在这种情况下,这种行为的结果似乎会引起麻烦。你觉得呢? - Xaxis
@Xaxis:我不明白这里的 clone 是什么意思。是指 map 吗?无论如何,JS 是弱类型语言,如果想要强制类型检查,可以加上显式的类型检测:if(typeof x == number)... else throw(...) - georg
我的 clone 方法可以深度复制一个数组或对象,并且可以选择在每个值上调用回调函数。... 是的,我很清楚我可以执行类型检查,但这将限制方法回调仅适用于数字类型的值。... 无论如何,非常感谢您的反馈! - Xaxis
@Xaxis:如果是这种情况,我期望clone([1,2,[3]])的结果是[2,4,[6]],并且回调函数在每个_原始_值上被调用。 - georg

4
这里发生的情况是,[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") 的结果是 NaN,而数字乘以 NaN 的结果是 NaN

1

0

//如果要将每个元素增加10%,可以使用以下代码:

let arr=[];
let array = [100, 200, 500, 1000];
array.forEach((p,i)=>arr[i]=(p*110/100));
console.log(arr);

//预期 [110,220,550,1100]


这并没有回答问题,问题是为什么 [3]*3 能够工作而 [1,2]*3 不能工作,而不是如何使它们工作。 - chrslg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接