Why is [1,2] + [3,4] = "1,23,4" in JavaScript?

Solution 1:

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/

Solution 2:

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.

Solution 3:

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.

Solution 4:

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]