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

时间:2021-02-16 07:56:58

I wanted to add the elements of an array into another, so I tried this:

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

[1,2] + [3,4]

It responded with:

它回答说:

"1,23,4"

What is going on?

什么是怎么回事?

13 个解决方案

#1


494  

The + operator is not defined for arrays.

+运算符不是为数组定义的。

What happens is that Javascript converts arrays into strings and concatenates those.

Javascript将数组转换成字符串并将其连接起来。

 

 

Update

Since this question and consequently my answer is getting a lot of attention I felt it would be useful and relevant to have an overview about how the + operator behaves in general also.

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

So, here it goes.

所以,在这里。

Excluding E4X and implementation-specific stuff, Javascript (as of ES5) has 6 built-in data types:

除了E4X和实现特定的内容,Javascript(如ES5)有6个内置数据类型:

  1. Undefined
  2. 未定义的
  3. Null
  4. Boolean
  5. 布尔
  6. Number
  7. 数量
  8. String
  9. 字符串
  10. Object
  11. 对象

Note that although typeof somewhat confusingly returns object for Null and function for callable Objects, Null is actually not an Object and strictly speaking, in specification-conforming Javascript implementations all functions are considered to be Objects.

请注意,尽管对于可调用对象的Null和函数的返回对象类型有点混乱,但Null实际上并不是一个对象,严格地说,在符合规范的Javascript实现中,所有函数都被认为是对象。

That's right - Javascript has no primitive arrays as such; only instances of an Object called Array with some syntactic sugar to ease the pain.

这是正确的——Javascript没有原始数组;只有一个被称为数组的对象的实例使用一些语法糖来减轻痛苦。

Adding more to the confusion, wrapper entities such as new Number(5), new Boolean(true) and new String("abc") are all of object type, not numbers, booleans or strings as one might expect. Nevertheless for arithmetic operators Number and Boolean behave as numbers.

添加更多的混乱,包装器实体,如新数字(5),新的布尔(真)和新字符串(“abc”)都是对象类型,不是数字,布尔值或字符串,正如人们所期望的那样。不过,对于算术运算符,数字和布尔行为是数字。

Easy, huh? With all that out of the way, we can move on to the overview itself.

容易吧,对不对?有了这些,我们就可以继续做概述了。

Different result types of + by operand types

操作和类型的不同结果类型。

            || 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 | 

* applies to Chrome13, FF6, Opera11 and IE9. Checking other browsers and versions is left as an exercise for the reader.

*适用于Chrome13、FF6、Opera11和IE9。检查其他浏览器和版本留给读者作为练习。

Note: As pointed out by CMS, for certain cases of objects such as Number, Boolean and custom ones the + operator doesn't necessarily produce a string result. It can vary depending on the implementation of object to primitive conversion. For example var o = { valueOf:function () { return 4; } }; evaluating o + 2; produces 6, a number, evaluating o + '2' produces '42', a string.

注意:正如CMS所指出的,对于某些对象,例如数字、布尔和自定义的对象,+运算符不一定会产生一个字符串结果。它可以根据对象的实现而变化,以进行原始转换。例如var o = {valueOf:function () {return 4;} };评估o + 2;产生6,一个数字,评价o + '2'产生'42',一个字符串。

To see how the overview table was generated visit http://jsfiddle.net/1obxuc7m/

要查看如何生成概述表,请访问http://jsfiddle.net/1obxuc7m/。

#2


240  

JavaScript's + operator has two purposes: adding two numbers, or joining two strings. It doesn't have a specific behaviour for arrays, so it's converting them to strings and then joining them.

JavaScript的+运算符有两个目的:添加两个数字或连接两个字符串。它对数组没有特定的行为,所以它将它们转换为字符串然后加入它们。

If you want to join two arrays to produce a new one, use the .concat method instead:

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

[1, 2].concat([3, 4]) // [1, 2, 3, 4]

If you want to efficiently add all elements from one array to another, you need to use the .push method:

如果想要高效地将所有元素从一个数组添加到另一个数组,需要使用.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]

The behaviour of the + operator is defined in ECMA-262 5e Section 11.6.1:

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

11.6.1 The Addition operator ( + )

The addition operator either performs string concatenation or numeric addition. The production AdditiveExpression : AdditiveExpression + MultiplicativeExpression is evaluated as follows:

加法运算符可以执行字符串连接或数字加法。生产添加剂的表达:加性表达+乘法表达量:

  1. Let lref be the result of evaluating AdditiveExpression.
  2. 让lref是评估添加表达式的结果。
  3. Let lval be GetValue(lref).
  4. 让lval GetValue(lref)。
  5. Let rref be the result of evaluating MultiplicativeExpression.
  6. 让rref是计算乘法表达式的结果。
  7. Let rval be GetValue(rref).
  8. 让rval GetValue(rref)。
  9. Let lprim be ToPrimitive(lval).
  10. 让lprim ToPrimitive(lval)。
  11. Let rprim be ToPrimitive(rval).
  12. 让rprim ToPrimitive(rval)。
  13. If Type(lprim) is String or Type(rprim) is String, then
    1. Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
    2. 返回字符串,这是连接ToString(lprim)和ToString(rprim)的结果
  14. 如果类型(lprim)是字符串或类型(rprim)是字符串,那么返回字符串,这是连接ToString(lprim)的结果,然后是ToString(rprim)
  15. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.
  16. 将添加操作的结果返回给ToNumber(lprim)和ToNumber(rprim)。参见11.6.3下面的说明。

You can see that each operand is converted ToPrimitive. By reading further we can find that ToPrimitive will always convert arrays to strings, producing this result.

您可以看到每个操作数都被转换为ToPrimitive。通过进一步阅读,我们可以发现,ToPrimitive将总是将数组转换为字符串,从而产生这个结果。

#3


43  

It adds the two arrays as if they were strings.

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

The string representation for the first array would be "1,2" and the second would be "3,4". So when the + sign is found, it cannot sum arrays and then concatenate them as being strings.

第一个数组的字符串表示形式是“1,2”,第二个数组是“3,4”。所以当找到+号时,它不能和数组相加然后将它们连接成字符串。

#4


39  

The + concats strings, so it converts the arrays to strings.

+ concats字符串,因此它将数组转换为字符串。

[1,2] + [3,4]
'1,2' + '3,4'
1,23,4

To combine arrays, use concat.

要组合数组,可以使用concat。

[1,2].concat([3,4])
[1,2,3,4]

#5


21  

In JavaScript, the binary addition operator (+) performs both numerical addition and string concatenation. However, when it's first argument is neither a number nor a string then it converts it into a string (hence "1,2") then it does the same with the second "3,4" and concatenates them to "1,23,4".

在JavaScript中,二进制加法运算符(+)同时执行数字加法和字符串连接。然而,当它的第一个参数既不是一个数字,也不是一个字符串,然后它将它转换成一个字符串(因此“1,2”),然后它对第二个“3,4”进行相同的操作,并将它们连接到“1,234,4”。

Try using the "concat" method of Arrays instead:

尝试使用数组的“concat”方法来代替:

var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];

#6


19  

It's converting the individual arrays to strings, then combining the strings.

它将单个数组转换为字符串,然后组合字符串。

#7


14  

It looks like JavaScript is turning your arrays into strings and joining them together. If you want to add tuples together, you'll have to use a loop or a map function.

看起来JavaScript将数组转换成字符串并将它们连接在一起。如果要将元组添加到一起,则必须使用循环或map函数。

#8


14  

[1,2]+[3,4] in JavaScript is same as evaluating:

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

new Array( [1,2] ).toString() + new Array( [3,4] ).toString();

and so to solve your problem, best thing would be to add two arrays in-place or without creating a new array:

为了解决你的问题,最好的方法是在不创建新数组的情况下添加两个数组:

var a=[1,2];
var b=[3,4];
a.push.apply(a, b);

#9


12  

It's doing exactly what you asked it to do.

它正在做你要求它做的事情。

What you're adding together are array references (which JS converts to strings), not numbers as it seems. It's a bit like adding strings together: "hello " + "world" = "hello world"

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

#10


8  

would be nice if you could overload operators in JavaScript but you can't: Can I define custom operator overloads in Javascript? you can only hack the "==" operator which converts to strings before comparing: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx

如果您可以在JavaScript中重载操作符,但是您不能:我可以定义自定义操作符重载JavaScript吗?您只能在比较:http://blogger.xs4all.nl/peterned/archive/2009/04/04/01/462517.aspx时,修改“==”操作符。

#11


8  

It is because, + operator assumes that the operands are string, if they are not numbers. So, it first converts them to string and concats to give the final result , if its not a number. Also, it does not support arrays.

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

#12


0  

Another result using just a simple "+" sign will be:

另一个使用简单的“+”符号的结果是:

[1,2]+','+[3,4] === [1,2,3,4]

So something like this should work (but!):

所以这样的事情应该奏效(但是!)

var a=[1,2];
var b=[3,4];
a=a+','+b; // [1,2,3,4]

... but it will convert the variable a from an Array to String! Keep it in mind.

…但它会将变量a从数组转换为字符串!记住它。

#13


0  

Some answers here have explained how the unexpected undesired output ('1,23,4') happens and some have explained how to obtain what they assume to be the expected desired output ([1,2,3,4]), i.e. array concatenation. However, the nature of the expected desired output is actually somewhat ambiguous because the original question simply states "I wanted to add the elements of an array into another...". That could mean array concatenation but it could also mean tuple addition (e.g. here and here), i.e. adding the scalar values of elements in one array to the scalar values of the corresponding elements in the second, e.g. combining [1,2] and [3,4] to obtain [4,6].

这里的一些答案已经解释了意外的非期望输出('1,23,4')如何发生,一些已经解释了如何获得预期的期望输出([1,2,3,4]),即数组连接。然而,预期期望输出的性质实际上有些模糊,因为最初的问题只是“我想把数组的元素添加到另一个…”。这可能意味着数组的连接,但也可能意味着数组的添加(例如,这里和这里),即在一个数组中添加元素的标量值,然后将其添加到相应元素的标量值中,例如将[1,2]和[3,4]组合得到[4,6]。

Assuming both arrays have the same arity/length, here is one simple solution:

假设两个数组都有相同的长度/长度,这里有一个简单的解决方案:

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]

#1


494  

The + operator is not defined for arrays.

+运算符不是为数组定义的。

What happens is that Javascript converts arrays into strings and concatenates those.

Javascript将数组转换成字符串并将其连接起来。

 

 

Update

Since this question and consequently my answer is getting a lot of attention I felt it would be useful and relevant to have an overview about how the + operator behaves in general also.

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

So, here it goes.

所以,在这里。

Excluding E4X and implementation-specific stuff, Javascript (as of ES5) has 6 built-in data types:

除了E4X和实现特定的内容,Javascript(如ES5)有6个内置数据类型:

  1. Undefined
  2. 未定义的
  3. Null
  4. Boolean
  5. 布尔
  6. Number
  7. 数量
  8. String
  9. 字符串
  10. Object
  11. 对象

Note that although typeof somewhat confusingly returns object for Null and function for callable Objects, Null is actually not an Object and strictly speaking, in specification-conforming Javascript implementations all functions are considered to be Objects.

请注意,尽管对于可调用对象的Null和函数的返回对象类型有点混乱,但Null实际上并不是一个对象,严格地说,在符合规范的Javascript实现中,所有函数都被认为是对象。

That's right - Javascript has no primitive arrays as such; only instances of an Object called Array with some syntactic sugar to ease the pain.

这是正确的——Javascript没有原始数组;只有一个被称为数组的对象的实例使用一些语法糖来减轻痛苦。

Adding more to the confusion, wrapper entities such as new Number(5), new Boolean(true) and new String("abc") are all of object type, not numbers, booleans or strings as one might expect. Nevertheless for arithmetic operators Number and Boolean behave as numbers.

添加更多的混乱,包装器实体,如新数字(5),新的布尔(真)和新字符串(“abc”)都是对象类型,不是数字,布尔值或字符串,正如人们所期望的那样。不过,对于算术运算符,数字和布尔行为是数字。

Easy, huh? With all that out of the way, we can move on to the overview itself.

容易吧,对不对?有了这些,我们就可以继续做概述了。

Different result types of + by operand types

操作和类型的不同结果类型。

            || 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 | 

* applies to Chrome13, FF6, Opera11 and IE9. Checking other browsers and versions is left as an exercise for the reader.

*适用于Chrome13、FF6、Opera11和IE9。检查其他浏览器和版本留给读者作为练习。

Note: As pointed out by CMS, for certain cases of objects such as Number, Boolean and custom ones the + operator doesn't necessarily produce a string result. It can vary depending on the implementation of object to primitive conversion. For example var o = { valueOf:function () { return 4; } }; evaluating o + 2; produces 6, a number, evaluating o + '2' produces '42', a string.

注意:正如CMS所指出的,对于某些对象,例如数字、布尔和自定义的对象,+运算符不一定会产生一个字符串结果。它可以根据对象的实现而变化,以进行原始转换。例如var o = {valueOf:function () {return 4;} };评估o + 2;产生6,一个数字,评价o + '2'产生'42',一个字符串。

To see how the overview table was generated visit http://jsfiddle.net/1obxuc7m/

要查看如何生成概述表,请访问http://jsfiddle.net/1obxuc7m/。

#2


240  

JavaScript's + operator has two purposes: adding two numbers, or joining two strings. It doesn't have a specific behaviour for arrays, so it's converting them to strings and then joining them.

JavaScript的+运算符有两个目的:添加两个数字或连接两个字符串。它对数组没有特定的行为,所以它将它们转换为字符串然后加入它们。

If you want to join two arrays to produce a new one, use the .concat method instead:

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

[1, 2].concat([3, 4]) // [1, 2, 3, 4]

If you want to efficiently add all elements from one array to another, you need to use the .push method:

如果想要高效地将所有元素从一个数组添加到另一个数组,需要使用.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]

The behaviour of the + operator is defined in ECMA-262 5e Section 11.6.1:

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

11.6.1 The Addition operator ( + )

The addition operator either performs string concatenation or numeric addition. The production AdditiveExpression : AdditiveExpression + MultiplicativeExpression is evaluated as follows:

加法运算符可以执行字符串连接或数字加法。生产添加剂的表达:加性表达+乘法表达量:

  1. Let lref be the result of evaluating AdditiveExpression.
  2. 让lref是评估添加表达式的结果。
  3. Let lval be GetValue(lref).
  4. 让lval GetValue(lref)。
  5. Let rref be the result of evaluating MultiplicativeExpression.
  6. 让rref是计算乘法表达式的结果。
  7. Let rval be GetValue(rref).
  8. 让rval GetValue(rref)。
  9. Let lprim be ToPrimitive(lval).
  10. 让lprim ToPrimitive(lval)。
  11. Let rprim be ToPrimitive(rval).
  12. 让rprim ToPrimitive(rval)。
  13. If Type(lprim) is String or Type(rprim) is String, then
    1. Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
    2. 返回字符串,这是连接ToString(lprim)和ToString(rprim)的结果
  14. 如果类型(lprim)是字符串或类型(rprim)是字符串,那么返回字符串,这是连接ToString(lprim)的结果,然后是ToString(rprim)
  15. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.
  16. 将添加操作的结果返回给ToNumber(lprim)和ToNumber(rprim)。参见11.6.3下面的说明。

You can see that each operand is converted ToPrimitive. By reading further we can find that ToPrimitive will always convert arrays to strings, producing this result.

您可以看到每个操作数都被转换为ToPrimitive。通过进一步阅读,我们可以发现,ToPrimitive将总是将数组转换为字符串,从而产生这个结果。

#3


43  

It adds the two arrays as if they were strings.

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

The string representation for the first array would be "1,2" and the second would be "3,4". So when the + sign is found, it cannot sum arrays and then concatenate them as being strings.

第一个数组的字符串表示形式是“1,2”,第二个数组是“3,4”。所以当找到+号时,它不能和数组相加然后将它们连接成字符串。

#4


39  

The + concats strings, so it converts the arrays to strings.

+ concats字符串,因此它将数组转换为字符串。

[1,2] + [3,4]
'1,2' + '3,4'
1,23,4

To combine arrays, use concat.

要组合数组,可以使用concat。

[1,2].concat([3,4])
[1,2,3,4]

#5


21  

In JavaScript, the binary addition operator (+) performs both numerical addition and string concatenation. However, when it's first argument is neither a number nor a string then it converts it into a string (hence "1,2") then it does the same with the second "3,4" and concatenates them to "1,23,4".

在JavaScript中,二进制加法运算符(+)同时执行数字加法和字符串连接。然而,当它的第一个参数既不是一个数字,也不是一个字符串,然后它将它转换成一个字符串(因此“1,2”),然后它对第二个“3,4”进行相同的操作,并将它们连接到“1,234,4”。

Try using the "concat" method of Arrays instead:

尝试使用数组的“concat”方法来代替:

var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];

#6


19  

It's converting the individual arrays to strings, then combining the strings.

它将单个数组转换为字符串,然后组合字符串。

#7


14  

It looks like JavaScript is turning your arrays into strings and joining them together. If you want to add tuples together, you'll have to use a loop or a map function.

看起来JavaScript将数组转换成字符串并将它们连接在一起。如果要将元组添加到一起,则必须使用循环或map函数。

#8


14  

[1,2]+[3,4] in JavaScript is same as evaluating:

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

new Array( [1,2] ).toString() + new Array( [3,4] ).toString();

and so to solve your problem, best thing would be to add two arrays in-place or without creating a new array:

为了解决你的问题,最好的方法是在不创建新数组的情况下添加两个数组:

var a=[1,2];
var b=[3,4];
a.push.apply(a, b);

#9


12  

It's doing exactly what you asked it to do.

它正在做你要求它做的事情。

What you're adding together are array references (which JS converts to strings), not numbers as it seems. It's a bit like adding strings together: "hello " + "world" = "hello world"

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

#10


8  

would be nice if you could overload operators in JavaScript but you can't: Can I define custom operator overloads in Javascript? you can only hack the "==" operator which converts to strings before comparing: http://blogger.xs4all.nl/peterned/archive/2009/04/01/462517.aspx

如果您可以在JavaScript中重载操作符,但是您不能:我可以定义自定义操作符重载JavaScript吗?您只能在比较:http://blogger.xs4all.nl/peterned/archive/2009/04/04/01/462517.aspx时,修改“==”操作符。

#11


8  

It is because, + operator assumes that the operands are string, if they are not numbers. So, it first converts them to string and concats to give the final result , if its not a number. Also, it does not support arrays.

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

#12


0  

Another result using just a simple "+" sign will be:

另一个使用简单的“+”符号的结果是:

[1,2]+','+[3,4] === [1,2,3,4]

So something like this should work (but!):

所以这样的事情应该奏效(但是!)

var a=[1,2];
var b=[3,4];
a=a+','+b; // [1,2,3,4]

... but it will convert the variable a from an Array to String! Keep it in mind.

…但它会将变量a从数组转换为字符串!记住它。

#13


0  

Some answers here have explained how the unexpected undesired output ('1,23,4') happens and some have explained how to obtain what they assume to be the expected desired output ([1,2,3,4]), i.e. array concatenation. However, the nature of the expected desired output is actually somewhat ambiguous because the original question simply states "I wanted to add the elements of an array into another...". That could mean array concatenation but it could also mean tuple addition (e.g. here and here), i.e. adding the scalar values of elements in one array to the scalar values of the corresponding elements in the second, e.g. combining [1,2] and [3,4] to obtain [4,6].

这里的一些答案已经解释了意外的非期望输出('1,23,4')如何发生,一些已经解释了如何获得预期的期望输出([1,2,3,4]),即数组连接。然而,预期期望输出的性质实际上有些模糊,因为最初的问题只是“我想把数组的元素添加到另一个…”。这可能意味着数组的连接,但也可能意味着数组的添加(例如,这里和这里),即在一个数组中添加元素的标量值,然后将其添加到相应元素的标量值中,例如将[1,2]和[3,4]组合得到[4,6]。

Assuming both arrays have the same arity/length, here is one simple solution:

假设两个数组都有相同的长度/长度,这里有一个简单的解决方案:

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]