我想将一个数组的元素添加到另一个数组中,所以我尝试了一下:
[1,2] + [3,4]
它回应:
"1,23,4"
到底是怎么回事?
[5,6,7][1,2]
是7
因为它使用了第二个数组中的最后一个项目。Oo
我想将一个数组的元素添加到另一个数组中,所以我尝试了一下:
[1,2] + [3,4]
它回应:
"1,23,4"
到底是怎么回事?
[5,6,7][1,2]
是7
因为它使用了第二个数组中的最后一个项目。Oo
Answers:
在+
操作者没有为数组定义。
发生的事情是Javascript 将数组转换为字符串并将其连接起来。
由于这个问题以及我的回答引起了很多关注,因此我认为对操作员的总体行为进行概述也将是有用且相关的+
。
所以,就到这里。
除E4X和实现特定的内容外,Javascript(自ES5起)具有6种内置数据类型:
请注意,尽管对于Null和可调用对象而言,typeof
返回值有些混乱 ,但Null实际上不是对象,严格来讲,在符合规范的Javascript实现中,所有函数都被视为对象。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所指出的,对于某些对象,例如和和自定义对象Number
,操作符不一定会产生字符串结果。它可以根据对象到原始转换的实现而有所不同。例如评估产品a ,评估产品a 。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)
- 返回应用加法运算的结果
ToNumber(lprim)
和ToNumber(rprim)
。请参见下面的注释11.6.3。
您可以看到每个操作数都已转换ToPrimitive
。通过进一步阅读,我们可以发现ToPrimitive
它将始终将数组转换为字符串,从而产生此结果。
Array.prototype.push.apply(data, [3, 4])
代替data.concat([3,4])
?
concat
产生一个新的数组,较长的调用有效地扩展了现有的数组。
[].push.apply(data, [3,4])
较少的冗长性。同样,这可以保证可以抵抗他人更改的值Array
。
它将两个数组视为字符串相加。
第一个数组的字符串表示形式为“ 1,2”,第二个数组的字符串表示形式为“ 3,4”。因此,当+
找到符号时,它不能对数组求和,然后将它们串联为字符串。
看来JavaScript会将数组转换成字符串并将其连接在一起。如果要一起添加元组,则必须使用循环或map函数。
它正在按照您要求的去做。
您要添加的是数组引用(JS将其转换为字符串),而不是数字。有点像将字符串加在一起:"hello " + "world"
="hello world"
如果您可以在JavaScript中重载运算符,但不能这样做,那就太好了:我可以在JavaScript中 定义自定义运算符重载吗? 您只能在比较之前修改“ ==”运算符并将其转换为字符串:http : //blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx
这是因为,+运算符假定操作数不是数字,而是字符串。因此,它首先将它们转换为字符串和concats,以给出最终结果(如果不是数字)。另外,它不支持数组。
这里的一些答案已经说明了意外的不希望有的输出('1,23,4'
)的发生方式,还有一些答案已经解释了如何获得假定为期望的所需输出([1,2,3,4]
)的内容,即数组串联。但是,期望的期望输出的性质实际上有点模棱两可,因为最初的问题只是说明“我想将数组的元素添加到另一个数组中……”。这可能意味着阵列串联,但它可能还意味着元组除了(例如这里和在这里),即添加元素的标量值在一个阵列中的对应的元件的标量值在第二,例如结合[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]