I was working on a problem for flattening arrays. I came across something really strange and can't seem to find an answer online about it.
Why does
[] + [1,2] = '1,2'
I can't seem to wrap my head around why adding an empty array to a populated one results in a string with the contents of the populated array.
What is happening behind the scenes that causes 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 far as I understand, reduce will set '[]' as the 'initial value' and thus for each element in the original array it will concatenate it with an empty array thus "flattening" the array.
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 thing as:
var coercion1 = "".concat({}.toString(), {foo: 'Foo', bar: 'Bar'}.toString()),
coercion2 = "".concat([].toString(), ['foo', 'bar'].toString());
console.log(coercion1);
console.log(coercion2);
Which is, again, the same thing 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 takes these steps:
- If the object has a toString() method, JavaScript calls it. If it returns a primitive value, JavaScript converts that value to a string (if it is not already a string) and returns the result of that conversion. [...]
- If the object has no toString() method, or if that method does not return a primitive value, then JavaScript looks for a valueOf() method. If the method exists, JavaScript calls it. If the return value is a primitive, JavaScript converts that value to a string (if it is not already) and returns the converted value.
- Otherwise, JavaScript cannot obtain a primitive value from either toString() or valueOf(), so it throws a TypeError.
David Flanagan, JavaScript: The Definitive Guide
This is happening because of JavaScript's implicit type coersion triggered by the +
operator. You can't simply perform a +
operation on arrays, so they are converted to strings (which contain the comma-separated string-converted values of the array).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With