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

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

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/

What is [1,2,3,4][1,2] in javascript

[1,2,3,4] is an array literal.

1,2 is two numbers with a comma operator between them, so resolves to 2.

So you are getting index 2 (the third item) from the array.

var array = [1,2,3,4];var property = (1,2);var result = array[property];
console.log({ array: array, property: property, result: result });

How [1,2] + [4,5,6][1] = 1,25 in JavaScript

Lets start with the last part and write it more verbose

var arr   = [4,5,6];
var value = arr[1];

Is the same as

[4,5,6][1]

and as arrays are zero based, that gives 5, so we really have

[1,2] + 5;

The first part is equal to

[1,2].toString(),

and that returns the string "1,2" because the array is converted to a string when trying to use it in an expression like that, as arrays can't be added to numbers, and then we have

"1,2" + 5

Concatenating strings with numbers gives strings, and adding the strings together we get

"1,25"

javascript [1,2,3,4] becomes 12, 23, 34

You can easily achieve the result using split, map, and filter

const num = 1234;
const result = String(num)
.split("")
.map((n, i, src) => (src.length !== i + 1 ? `${n}${src[i + 1]}` : null))
.filter(Boolean)
.map(Number);

console.log(result);

javascript [1,2,3,4,5,6,7] becomes 123, 234, 345, 456 etc

The simplest solution will be to loop over the array and loop until length - 2 as:

const num = 1234567;
const strNum = String(num);
const result = [];

for (let i = 0; i < strNum.length - 2; ++i) {
result.push(strNum.slice(i, i + 3));
}
console.log(result);

Why array + array returns a string?

That's just how JavaScript works. Both are objects, there's not a defined thing for + between an Array and an Array, so it does the default thing of converting to String and concatenating them (still as a String).

Use the Array.prototype.concat method to acheive your goal.

let array = [1, 2]

let array2 = [3, 4]

let array3 = array.concat(array2);

console.log(array3) // [1, 2, 3, 4]

Why does adding an array to number return a string?

Can anyone explain this behaviour?

This answer attempts to explain this behavior from the point of view of spec.

As per spec, during the run-time evaluation of +, both expressions (left and right) are converted to their primitive values.


  1. Let lprim be ToPrimitive(lval).
  2. Let rprim be ToPrimitive(rval).

toPrimitive tries to pass hint:number (since invoked during arithmetic evaluation) to OrdinaryToPrimitive


  1. If hint is "string", then

    a. Let methodNames be «"toString", "valueOf"».
  2. Else,

    b. Let methodNames be «"valueOf", "toString"». //this gets invoked

Since one of the values were casted to string via 4a) above, string concatenation takes place.

Hence

[1,2,4] + 1 => [1,2,4].toString() + "1" => "1,2,4" + "1" => (finally) "1,2,41"

Browser behavior while trying directly add arrays and objects

The behavior of addition operator (+) is pretty well stated in spec.

As you can see, before returning the sum, both operands are get converted to primitive:


  1. Let lprim be ToPrimitive(lval).
  2. Let rprim be ToPrimitive(rval).

Now let's see what ToPrimitive actually returns here. Well, it returns the same input for all types, except for Objects:

Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

So, for example for Arrays, we get a string of its elements joined with commas:

var arr = [1, 2, 3];   // "1,2,3"

Because for default value it returns the result of toString function, if it's a primitive value.

For Objects, it's by default the following string: [object Object].

Now getting back to ToPrimitive. Point 7 states that if one of the operands is a string, the other is also converted to string and the concatenation of both is returned. That's why in your case:

var e = ["red", "green", "blue"];
var f = ["lily", "Lotus"];
console.log(e + f);
  1. e becomes "red,green,blue"
  2. f becomes "lily,Lotus"
  3. the concatenation is returned, i.e "red,green,bluelily,Lotus"

The same for objects. Regardless of contents, the object.toString() becomes [object Object] and the sum of your objects will result in "[object Object][object Object]".

As you can see, in the other cases (point 8), it will try to convert operands to numbers and then return the sum of them.



Related Topics



Leave a reply



Submit