为什么JavaScript中的[1,2] + [3,4] ="1,23,4"?

oke*_*een 401 javascript arrays string concatenation

我想将数组的元素添加到另一个中,所以我尝试了这个:

[1,2] + [3,4]
Run Code Online (Sandbox Code Playgroud)

它回应:

"1,23,4"
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?

Sau*_*aul 512

+操作者没有为数组定义.

会发生什么是Javascript 将数组转换为字符串并连接它们.

 

更新

由于这个问题,因此我的答案得到了很多关注,我觉得有一个关于操作员一般行为的概述是有用的和相关的+.

所以,在这里.

排除E4X和特定于实现的东西,Javascript(从ES5开始)有6种内置数据类型:

  1. 未定义
  2. 空值
  3. 布尔
  4. 宾语

请注意,尽管Null和可调用对象typeof 有点令人困惑地返回 ,但Null实际上不是Object,严格来说,在符合规范的Javascript实现中,所有函数都被认为是对象.objectfunction

那是对的 - Javascript 没有原始数组 ; 只有一个Object的实例Array用一些语法糖调用来缓解疼痛.

添加更多的混淆,包装实体,如new Number(5),new Boolean(true)new String("abc")所有object类型,而不是数字,布尔或字符串,如人们所期望的那样.然而,算术运算符NumberBoolean行为数字.

好吗,对吧?完成所有这些后,我们可以继续进行概述.

+操作数类型的不同结果类型

            || 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 | 
Run Code Online (Sandbox Code Playgroud)

*适用于Chrome13,FF6,Opera11和IE9.检查其他浏览器和版本是留给读者的练习.

注:正如指出的CMS,用于物体如某些情况下Number,Boolean和自定义的的+运营商并不一定产生一个字符串结果.它可以根据对象到原始转换的实现而变化.例如,var o = { valueOf:function () { return 4; } };评估o + 2;生产6,a number,评估o + '2'生产'42',a string.

要查看概述表的生成方式,请访问http://jsfiddle.net/1obxuc7m/


小智 244

JavaScript的+运算符有两个用途:添加两个数字或连接两个字符串.它没有数组的特定行为,因此它将它们转换为字符串然后加入它们.

如果要连接两个数组以生成新数组,请改用.concat方法:

[1, 2].concat([3, 4]) // [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

如果要有效地将一个数组中的所有元素添加到另一个数组,则需要使用.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]
Run Code Online (Sandbox Code Playgroud)

+运营商的行为在ECMA-262 5e第11.6.1节中定义:

11.6.1加法运算符(+)

加法运算符执行字符串连接或数字加法.生产AdditiveExpression : AdditiveExpression + MultiplicativeExpression评估如下:

  1. 让我们lref评估的结果AdditiveExpression.
  2. 我们lvalGetValue(lref).
  3. 让我们rref评估的结果MultiplicativeExpression.
  4. 我们rvalGetValue(rref).
  5. 我们lprimToPrimitive(lval).
  6. 我们rprimToPrimitive(rval).
  7. 如果Type(lprim)String或者Type(rprim)String,则
    1. 返回串联ToString(lprim)后跟的结果字符串ToString(rprim)
  8. 将添加操作的结果返回到ToNumber(lprim)ToNumber(rprim).见11.6.3下面的注释.

您可以看到每个操作数都已转换ToPrimitive.通过进一步阅读,我们可以发现ToPrimitive将始终将数组转换为字符串,从而产生此结果.

  • +1作为这个答案不仅解释了问题,而且还解释了如何正确地做到这一点. (7认同)
  • @evilcelery:他们服务于不同的目的.`concat`生成一个*new*Array,较长的调用有效地扩展了*existing*Array. (5认同)
  • 这里有一点点,但我同意schnaader.最佳答案解释了被问及的问题/错误/行为,然后展示了如何产生预期结果.+1 (3认同)

Dou*_*oug 43

它将两个数组添加为字符串.

第一个数组的字符串表示形式为"1,2",第二个数组的字符串表示形式为"3,4".因此,当+找到符号时,它不能对数组求和,然后将它们连接为字符串.


Roc*_*mat 40

+concats字符串,因此它的数组转换为字符串.

[1,2] + [3,4]
'1,2' + '3,4'
1,23,4
Run Code Online (Sandbox Code Playgroud)

要组合数组,请使用concat.

[1,2].concat([3,4])
[1,2,3,4]
Run Code Online (Sandbox Code Playgroud)


mae*_*ics 21

在JavaScript中,二元加法运算符(+)执行数字加法和字符串连接.但是,当它的第一个参数既不是数字也不是字符串时,它将它转换为字符串(因此为" 1,2"),然后它与第二个" 3,4" 相同,并将它们连接到" 1,23,4".

尝试使用数组的"concat"方法:

var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
Run Code Online (Sandbox Code Playgroud)


tad*_*man 19

它将各个数组转换为字符串,然后组合字符串.


Ada*_*cki 14

看起来JavaScript正在将数组转换为字符串并将它们连接在一起.如果要将元组一起添加,则必须使用循环或映射函数.


use*_*806 14

[1,2]+[3,4] 在JavaScript中与评估相同:

new Array( [1,2] ).toString() + new Array( [3,4] ).toString();
Run Code Online (Sandbox Code Playgroud)

所以要解决你的问题,最好的办法是在原地添加两个数组或不创建新数组:

var a=[1,2];
var b=[3,4];
a.push.apply(a, b);
Run Code Online (Sandbox Code Playgroud)


Jam*_*xon 12

它完全按照你的要求去做.

你在一起添加的是数组引用(JS转换为字符串),而不是看起来像数字.这有点像添加字符串:"hello " + "world"="hello world"

  • 呵呵,它总是按照我的要求行事.问题是要问好问题.引起我兴趣的是添加数组时对数组的toString()解释. (5认同)

Pra*_*ngh 8

这是因为,+运算符假设操作数是字符串,如果它们不是数字.因此,如果它不是数字,它首先将它们转换为字符串和concats以给出最终结果.此外,它不支持数组.

  • +运算符不能假设操作数是字符串,因为1 + 1 == 2等等.这是因为'+'没有为数组定义,所以它toString -s它们. (2认同)

Geo*_*lis 8

如果你可以在JavaScript中重载运算符但是你不能: 我可以在Javascript中定义自定义运算符重载吗? 你只能破解比较之前转换为字符串的"=="运算符:http: //blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx