Javascript quirky type coercion.

[] + [] = ? | [] + {} = ? | {} + [] = ? | {} + {} = ?

Taras Pashko
Apr 25 · 2 min read

During the interview, you can often get a question such as what would be the result of [] + {}. And some times you can’t understand why it will be

This article explains the type conversion of non-primitives in a browser.


[] + [] = “” — returns an empty string. That happens because we are trying to add two arrays (objects), not number or string. And in Javascript, only numbers or strings supposed to be added. All other values except for those will be converted to either one of string or number.

That’s why ToPrimitive will be called.

Internal operation ToPrimitive(input, PreferredType?) has optional parameter PreferredType which is Number or String. If PreferredType is Number, the following steps are performed to convert the value input:

  • If the input is primitive, return it as is.
  • Otherwise, input is an object. Call obj.valueOf(). If the result is primitive, return it.
  • Otherwise, call obj.toString(). If the result is a primitive, return it.
  • Otherwise, throw a TypeError

If PreferredType is String:

  • If the input is primitive, return it as is.
  • Otherwise, call obj.toString(). If the result is a primitive, return it.
  • Otherwise, the input is an object. Call obj.valueOf(). If the result is primitive, return it.
  • Otherwise, throw a TypeError

So when ToPrimitive is called we have the next:

[].valueOf() -> (this)

As the result is not primitive toString is called, and we have empty string as the result. Therefore, the result of [] + [] is the concatenation of two empty strings.


[] + {} = “[object Object]”, here we have already expected conversion of the empty array to an empty string. Converting an empty object, String({}) operation will be salled and the result will be “[object Object]”. And the empty string will be concatenated with the result of converting an emty object to a string.


{} + [] = 0. In this case the empty object is interpreted as an empty code block and will be ignored. The whole input is parsed as a statement, that’s why curly braces are interpreted as start of a code block. And following +[] will be converted as next:

Number([]) -> Number([].valueOf()) -> isn’t primitive -> Number(“”) -> 0


{} + {} = “[object Object][object Object]”. Will be parsed as an expression and so we will get as a result concatenation of two String({}).


But an empty object at the beginning can be interpreted differently in different browsers. For example in Firefox {} + {} you’ll got NaN as a result. This happens because the first empty object will be interpreted as an empty code block and it will be ignored and /the/ statement +{} will be converted /to/:
Number({}) -> Number({}.valueOf()) -> non-primitive -> Number(“[object Object]”) -> NaN


I hope now you understand the “weird” behavior of Javascript. And when you will face this question at your next interview you will able easily explain type coercion in Javascript.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade