我想将数组的元素添加到另一个中,所以我尝试了这个:
[1,2] + [3,4]
回复:
"1,23,4"
发生了什么事?
答案 0 :(得分:505)
未为数组定义+
运算符。
Javascript 将数组转换为字符串并将其连接起来。
由于这个问题以及我的答案得到了很多关注,我觉得对+
运算符的行为也有一个概述是有用和相关的。< / p>
所以,就在这里。
排除E4X和特定于实现的内容,Javascript(从ES5开始)内置{strong> 6 <{3}}:
请注意,尽管typeof
data types object
表示Null,function
表示可调用对象,但Null实际上不是对象,严格来说,在符合规范的Javascript实现中函数被认为是对象。
没错 - 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。检查其他浏览器和版本是留给读者的练习。
注意:正如somewhat confusingly returns所指出的那样,对于Number
,Boolean
和自定义对象的某些情况+
运算符不一定产生字符串结果。它可以根据对象到原始转换的实现而变化。例如var o = { valueOf:function () { return 4; } };
评估o + 2;
生成6
,number
,评估o + '2'
生成'42'
,string
。
要查看概述表的生成方式,请访问CMS
答案 1 :(得分:243)
JavaScript的+
运算符有两个用途:添加两个数字或连接两个字符串。它没有数组的特定行为,因此它将它们转换为字符串然后加入它们。
如果要加入两个数组以生成新数组,请改用the .concat
method:
[1, 2].concat([3, 4]) // [1, 2, 3, 4]
如果要有效地将所有元素从一个数组添加到另一个数组,则需要使用the .push method:
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 Section 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)
- 将添加操作的结果返回到
醇>ToNumber(lprim)
和ToNumber(rprim)
。参见下面的注释11.6.3。
您可以看到每个操作数都已转换为ToPrimitive
。通过进一步阅读,我们可以发现ToPrimitive
将始终将数组转换为字符串,从而产生此结果。
答案 2 :(得分:43)
它将两个数组添加为字符串。
第一个数组的字符串表示形式为“1,2”,第二个数组的字符串表示形式为“3,4”。因此,当找到+
符号时,它不能对数组求和,然后将它们连接为字符串。
答案 3 :(得分:40)
+
concats字符串,因此它将数组转换为字符串。
[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
要组合数组,请使用concat
。
[1,2].concat([3,4])
[1,2,3,4]
答案 4 :(得分:21)
在JavaScript中,二元加法运算符(+
)执行数字加法和字符串连接。但是,当它的第一个参数既不是数字也不是字符串时,它会将其转换为字符串(因此为“1,2
”)然后它与第二个“3,4
”相同并将它们连接到“ 1,23,4
”。
尝试使用Arrays的“concat”方法:
var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
答案 5 :(得分:19)
它将各个数组转换为字符串,然后组合字符串。
答案 6 :(得分:14)
看起来JavaScript正在将数组转换为字符串并将它们连接在一起。如果要将元组一起添加,则必须使用循环或映射函数。
答案 7 :(得分:14)
[1,2]+[3,4]
与评估相同:
new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
所以要解决你的问题,最好的办法是在原地添加两个数组或不创建新数组:
var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
答案 8 :(得分:12)
它完全按照你的要求去做。
你一起添加的是数组引用(JS转换为字符串),而不是看起来像数字。这有点像在一起添加字符串:"hello " + "world"
= "hello world"
答案 9 :(得分:8)
这是因为,+运算符假设操作数是字符串,如果它们不是数字。因此,如果它不是数字,它首先将它们转换为字符串和concats以给出最终结果。此外,它不支持数组。
答案 10 :(得分:8)
会很好,但你不能: Can I define custom operator overloads in Javascript? 你只能破解比较之前转换为字符串的“==”运算符: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
答案 11 :(得分:0)
仅使用简单的“+”符号的另一个结果是:
[1,2]+','+[3,4] === [1,2,3,4]
所以这样的事情应该有效(但是!):
var a=[1,2];
var b=[3,4];
a=a+','+b; // [1,2,3,4]
...但它会将变量a从Array转换为String!记住这一点。
答案 12 :(得分:0)
这里的一些答案已经解释了意外的非期望输出('1,23,4'
)是如何发生的,并且一些已经解释了如何获得他们认为是预期的期望输出([1,2,3,4]
),即阵列级联。然而,预期的期望输出的性质实际上有些模棱两可,因为原始问题只是简单地说明了#34;我想将数组的元素添加到另一个......&#34;。 可能意味着数组连接,但它也意味着元组添加(例如here和here),即在一个元素中添加元素的标量值数组到第二个中相应元素的标量值,例如合并[1,2]
和[3,4]
以获取[4,6]
。
假设两个阵列具有相同的arity / length,这是一个简单的解决方案:
const arr1 = [1, 2];
const arr2 = [3, 4];
const add = (a1, a2) => a1.map((e, i) => e + a2[i]);
console.log(add(arr1, arr2)); // ==> [4, 6]
&#13;