410

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?

Sнаđошƒаӽ
  • 13,406
  • 11
  • 67
  • 83
okeen
  • 3,908
  • 2
  • 12
  • 19
  • 1
    Here's a question related to this topic: http://stackoverflow.com/questions/1724255/why-does-2-2-in-javascript – Xavi Aug 23 '11 at 17:05
  • 29
    Ah-ha-ha, sadist interviewer can ask even something like - what this will return [1,2] + [5,6,7][1,2]. why? – shabunc Aug 23 '11 at 17:09
  • 9
    I think [1,2] + [3,4] has been the most evaluated expression in firebug this week, after alert('crap'). – okeen Aug 23 '11 at 22:35
  • 6
    Wanna laugh ? Try [] + [], {} + [], {} + {}, and [] + {} – Intrepidd Nov 22 '12 at 23:31
  • 1
    @shabunc - care to explain why `[5,6,7][1,2]` is `7` because it uses the last item in the second array. O.o – vsync Apr 25 '15 at 20:13
  • 1
    @vsync - I'm very bad with "care to explain" construction, since I'm not native speaker? So, you are basicall asking why? Becase well, list ot comma separated values resolves to last one in "take index" context. – shabunc Apr 27 '15 at 16:28
  • @shabunc - so weird. I wish there was a video of the meeting when "they" had decided on all those weird things. I really would like to watch how they had got to be. – vsync Apr 27 '15 at 17:11
  • 1
    @vsync I'm guessing that's not the full picture. Compare the nearly-identical `[1,2]+[5,6][1,2]`, which apparently evaluates to `"1,2undefined"`! JavaScript is inhumane. Why are we so collectively committed to perpetrating this pain? – clozach Jul 16 '18 at 00:17
  • You must be new to Javascript. – Magnus Lind Oxlund Mar 18 '20 at 17:10

13 Answers13

522

The + operator is not defined for arrays.

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

 

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:

  1. Undefined
  2. Null
  3. Boolean
  4. Number
  5. String
  6. Object

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.

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.

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.

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.

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.

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

Community
  • 1
  • 1
Saul
  • 17,210
  • 8
  • 57
  • 85
245

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.

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

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

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:

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. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating MultiplicativeExpression.
  4. Let rval be GetValue(rref).
  5. Let lprim be ToPrimitive(lval).
  6. Let rprim be ToPrimitive(rval).
  7. 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)
  8. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 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.

Jeremy
  • 1
  • 77
  • 324
  • 346
  • 7
    +1 as this answer not only explains the problem, but also explains how to do it right. – schnaader Aug 19 '11 at 18:11
  • 3
    there's a little tmi here, but I agree with schnaader. The best answers explain the problem/error/behavior that's being asked about then shows how to produce the intended result. +1 – matthewdunnam Aug 19 '11 at 20:38
  • 1
    Why would you use the more verbose `Array.prototype.push.apply(data, [3, 4])` instead of `data.concat([3,4])`? – evilcelery Aug 22 '11 at 10:37
  • 5
    @evilcelery: They serve different purposes. `concat` produces a *new* Array, the longer call efficiently extends an *existing* Array. – Jeremy Aug 22 '11 at 10:40
  • 1
    You can use `[].push.apply(data, [3,4])` for slightly less verbosity. Also, that is guaranteed to be resistant to other people changing the value of `Array`. – Sam Tobin-Hochstadt Jan 11 '12 at 13:52
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.

Doug
  • 6,097
  • 3
  • 26
  • 47
  • Yes, that is the first and unique explanation comming to the mind but, isn't that a very weird behaviour? maybe there's some dark, unknow operation / transformation being done, and I would love to know the inners :P – okeen Aug 19 '11 at 16:58
40

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

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

To combine arrays, use concat.

[1,2].concat([3,4])
[1,2,3,4]
Rocket Hazmat
  • 204,503
  • 39
  • 283
  • 323
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".

Try using the "concat" method of Arrays instead:

var a = [1, 2];
var b = [3, 4];
a.concat(b) ; // => [1, 2, 3, 4];
maerics
  • 133,300
  • 39
  • 246
  • 273
19

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

tadman
  • 194,930
  • 21
  • 217
  • 240
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.

Adam Fabicki
  • 530
  • 3
  • 10
14

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

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);
user286806
  • 485
  • 1
  • 5
  • 14
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"

Jamie Dixon
  • 49,653
  • 18
  • 119
  • 157
  • 5
    hehe, it ALWAYS does what I asked. The problem is to ask the good question. What intrigues me is the toString() interpretation of the arrays when you add them. – okeen Aug 19 '11 at 17:00
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.

Prashant Singh
  • 3,595
  • 12
  • 56
  • 105
  • 2
    The + operator can NOT assume the operands are strings, because 1 + 1 == 2, among others. It's because '+' is not defined for arrays, so it toString-s them. – okeen Aug 20 '11 at 11:32
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

Community
  • 1
  • 1
George Birbilis
  • 2,295
  • 2
  • 25
  • 33
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].

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]
Community
  • 1
  • 1
Andrew Willems
  • 9,768
  • 8
  • 39
  • 58
-1

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.