Most of us working regularly with JavaScript are already more or less accustomed to some of the unexpected, quirky behavior it exhibits.
Take this classic example:
3 + "3" // "33"
Here’s one I stumbled across that really made me pause:
{} + [] // 0
Take a wild guess why this happens.
It’s because {}
is not treated as an object literal here — instead, it’s interpreted as an empty code block. That leaves us with:
+[] // => 0
The unary +
coerces the empty array into a number, and the result is 0.
🧩 More Examples of Type Coercion
The Stack Overflow answer I found also mentions:
[] + {} // "[object Object]"
Here, []
is treated as an empty string, and {}
is treated as an object literal. JavaScript tries to concatenate them as strings — hence: "[object Object]"
.
How about:
[] + [] // ""
Straightforward, right? Both arrays are treated as empty strings. Concatenating two empty strings gives… an empty string.
And then there's this one:
{} + {} // NaN
This one’s a little trickier. The first {}
is still treated as a code block. The second {}
is coerced using the +
operator. Since objects can’t be coerced into numbers, the result is NaN
.
⚙️ Why It Matters in Real Code
I know, nobody is adding arrays and objects. This stuff is mostly a part of JS trivia.
But I actually stumbled into something similar that led me down the "type and coercion" rabbit hole.
const pl = // some complex formula with no type safety
if (pl) {
// update UI
}
The bug? Sometimes pl was 0, and the block didn’t execute — because 0 is falsy in JavaScript.
At first, the condition seemed intended to guard against undefined
or null
. So we tried a safer check:
if (typeof pl === "number") {
// update UI
}
Pretty solid — except for one catch:
typeof NaN // "number"
Yep. NaN
is of type "number".
So this condition passed even when pl
was NaN
, and the UI still updated with invalid values.
We ended up adding a combination of checks (like !isNaN(pl)
) and some stronger type safety upstream.
📌 Takeaways
It’s good to experiment with “obvious cases that would never happen in real life” to see how a programming language actually handles them. And also because it's fun.
Here are a few more I found interesting:
isNaN(null) // false; null is coerced to 0
isNaN([]) // false; [] coerced to 0
isNaN("") // false; "" coerced to 0
isNaN(true) // false; coerced to 1
isNaN(false) // false; coerced to 0
isNaN("text") // true
isNaN({}) // true; object can't be coerced to a number
isNaN(undefined) // true; undefined, not be coerced to a number; NaN
Got a favorite weird JavaScript case? Share it in the comments. Always open to learning something new.
Top comments (1)
sdf