JavaScript: Arrays. Why does concatenating an empty array with a filled array result in a string?
I was working on a problem for flattening arrays. I stumbled upon something really weird and cannot find an answer on the internet about this.
Why
[] + [1,2] = '1,2'
I can't seem to wrap my head around why adding an empty array to a filled one results in a line with the contents of the filled array.
What's going on behind the scenes causing this?
Example from my code:
arr = [1, [2], [3, 4]];
arr.reduce(flatten, []); // [1, 2, 3, 4]
function flatten(a, b) {
return a.concat(b);
}
As I understand it, reduce will set '[]' as the "initial value", and thus, for each element in the original array, it will concatenate it to an empty array, thus "flattening" the array.
source to share
This is due to JavaScript implicit type conversion caused by the operator +
. You cannot just perform an operation +
on arrays, so they are converted to strings (which contain comma separated values ββconverted to array string).
source to share
When you use +
between objects (arrays are objects), JavaScript calls toString()
and / or valueOf()
internally.
var coercion1 = {} + {foo: 'Foo', bar: 'Bar'},
coercion2 = [] + ['foo', 'bar'];
console.log(coercion1);
console.log(coercion2);
This is the same as:
var coercion1 = "".concat({}.toString(), {foo: 'Foo', bar: 'Bar'}.toString()),
coercion2 = "".concat([].toString(), ['foo', 'bar'].toString());
console.log(coercion1);
console.log(coercion2);
The same as:
var coercion1 = "".concat({}.valueOf(), {foo: 'Foo', bar: 'Bar'}.valueOf()),
coercion2 = "".concat([].valueOf(), ['foo', 'bar'].valueOf());
console.log(coercion1);
console.log(coercion2);
To convert an object to a string, JavaScript does the following:
- If the object has a toString () method , JavaScript calls it. If it returns a primitive value, JavaScript converts that value to a string (if not already a string) and returns the result of that conversion. [...]
- If the object does not have a toString () method, or if that method does not return a primitive value, then JavaScript looks for valueOf () . If the method exists, JavaScript calls it. If the return value is primitive, JavaScript converts that value to a string (if not already provided) and returns the converted value.
- Otherwise JavaScript cannot get a primitive value from toString () or valueOf () , so it throws a TypeError.
David Flanagan , JavaScript: The Ultimate Guide
source to share