为什么在 JavaScript 中 [1,2] + [3,4] = “1,23,4”?
我想将数组的元素添加到另一个数组中,所以我尝试了这个:
[1,2] + [3,4]
它的回应是:
"1,23,4"
这是怎么回事?
我想将数组的元素添加到另一个数组中,所以我尝试了这个:
[1,2] + [3,4]
它的回应是:
"1,23,4"
这是怎么回事?
未为数组定义运算符。+
发生的事情是Javascript将数组转换为字符串并连接它们。
由于这个问题以及我的答案得到了很多关注,我认为对操作员的一般行为进行概述也是有用且相关的。+
所以,它开始了。
除了E4X和特定于实现的东西,Javascript(从ES5开始)有6种内置数据类型:
请注意,尽管对于 Null 和可调用对象,Null 的返回有点令人困惑,但 Null 实际上不是对象,严格来说,在符合规范的 Javascript 实现中,所有函数都被视为对象。typeof
object
function
没错 - Javascript没有原始数组;只有对象的实例用一些句法糖调用以减轻疼痛。Array
更令人困惑的是,包装实体(如 )和所有类型,而不是人们可能期望的数字,布尔值或字符串。然而,对于算术运算符和表现为数字。new Number(5)
new Boolean(true)
new String("abc")
object
Number
Boolean
很简单,对吧?完成所有这些之后,我们可以继续进行概述本身。
按操作数类型划分的不同结果类型 +
|| undefined | null | boolean | number | string | object |
=========================================================================
undefined || number | number | number | number | string | string |
null || number | number | number | number | string | string |
boolean || number | number | number | number | string | string |
number || number | number | number | number | string | string |
string || string | string | string | string | string | string |
object || string | string | string | string | string | string |
* 适用于 Chrome13、FF6、Opera11 和 IE9。检查其他浏览器和版本留给读者作为练习。
注意:正如 CMS 所指出的,对于对象(如 和 自定义对象)的某些情况,运算符不一定生成字符串结果。它可能因对象到基元转换的实现而异。例如,计算产生 ,a ,计算产生,a 。Number
Boolean
+
var o = { valueOf:function () { return 4; } };
o + 2;
6
number
o + '2'
'42'
string
要查看概览表的生成方式,请访问 http://jsfiddle.net/1obxuc7m/
JavaScript的运算符有两个目的:将两个数字相加,或连接两个字符串。它没有数组的特定行为,因此它将它们转换为字符串,然后将它们连接起来。+
如果要联接两个数组以生成一个新数组,请改用 .concat
方法:
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
如果要有效地将所有元素从一个数组添加到另一个数组,则需要使用 .push 方法:
var data = [1, 2];
// ES6+:
data.push(...[3, 4]);
// or legacy:
Array.prototype.push.apply(data, [3, 4]);
// data is now [1, 2, 3, 4]
ECMA-262 5e 第 11.6.1 节中定义了操作员的行为:+
11.6.1 加法运算符 ( + )
加法运算符执行字符串串联或数字加法。生产评估如下:
AdditiveExpression : AdditiveExpression + MultiplicativeExpression
- 让我们成为评估的结果。
lref
AdditiveExpression
- 听任。
lval
GetValue(lref)
- 让我们成为评估的结果。
rref
MultiplicativeExpression
- 听任。
rval
GetValue(rref)
- 听任。
lprim
ToPrimitive(lval)
- 听任。
rprim
ToPrimitive(rval)
- 如果 是 或 是 ,则
Type(lprim)
String
Type(rprim)
String
- 返回字符串,该字符串是串联的结果,后跟
ToString(lprim)
ToString(rprim)
- 返回对 和 应用加法运算的结果。请参阅下面的注释 11.6.3。
ToNumber(lprim)
ToNumber(rprim)
您可以看到每个操作数都已转换。通过进一步阅读,我们可以发现它将始终将数组转换为字符串,从而产生此结果。ToPrimitive
ToPrimitive