Every developer has that one moment when JavaScript makes them question their career choices and life.
You write a simple expression, expect a reasonable result, and JavaScript responds like it has its own interpretation of reality.
Let's look at some JavaScript moments that feel less like programming and more like negotiating with a very unpredictable roommate.
1. Empty arrays are apparently very social
console.log([] + []); // "" Two empty arrays meet.
They have nothing to say.
A completely silent conversation.
But wait...
console.log([] + {}); // "[object Object]" Now the array meets an object, and suddenly JavaScript starts introducing people by their full legal names.
2. The famous equality crisis
console.log(0 == false); // true console.log("" == false); // true console.log(null == undefined); // true console.log(null == 0); // false JavaScript's loose equality operator is basically a matchmaking service.
It can find relationships between values that have absolutely nothing in common.
But apparently, null and 0 have decided to remain strangers.
Developer: Why?
This article was prepared with: It's complicated.
3. NaN is not even equal to itself
console.log(NaN === NaN); // false Imagine introducing yourself to yourself and getting rejected.
That's NaN.
Thankfully, JavaScript gives us a way to check it:
console.log(Number.isNaN(NaN)); // true At least someone understands NaN.
4. The array that refuses to be empty
const items = []; if (items) { console.log("We have items!"); } Output:
We have items! But there are no items!
JavaScript treats empty arrays as truthy.
Remember:
Boolean([]); // true Boolean({}); // true Boolean(""); // false Boolean(0); // false An empty shopping cart is apparently full of confidence.
5. Addition has an identity crisis
console.log("5" - 2); // 3 console.log("5" + 2); // "52" Subtraction: Let's do some mathematics.
Addition: Let's start a string concatenation business.
Same language. Different personalities.
6. Floating-point mathematics: A tiny betrayal
console.log(0.1 + 0.2); // 0.30000000000000004 I asked for 0.3.
JavaScript delivered 0.30000000000000004.
That extra number wasn't in the requirements.
This happens because JavaScript uses IEEE 754 binary floating-point numbers for ordinary numeric calculations. Some decimal fractions cannot be represented exactly in binary.
For money calculations, use integer minor units (like paise or cents), or an appropriate decimal arithmetic library.
7. Bonus: The classic typeof surprise
console.log(typeof null); // "object" This is a historical quirk in JavaScript.
It isn't a useful way to check for null. Use:
const value = null; console.log(value === null); // true Sometimes the best solution is simply to be explicit.
So, is JavaScript actually bad?
Not really.
JavaScript is incredibly useful, flexible, and powerful. These behaviors are mostly consequences of its history, design decisions, and type-coercion rules.
But understanding them can save us from some very confusing debugging sessions.
A few habits worth keeping:
- Prefer
===over==unless you intentionally need coercion. - Use
Number.isNaN()to check for NaN. - Remember that empty arrays and objects are truthy.
- Be careful with floating-point calculations.
- Use explicit type conversions when working with external data.
Final thoughts
JavaScript isn't necessarily trying to confuse us.
It's just a language with a very interesting sense of humor.
And somewhere, a developer is still debugging why [] + {} returned something that looks like an object introducing itself at a networking event.
What's your favorite JavaScript WTF moment?
Share it in the comments. Let's laugh, learn, and debug together. 😂
![JavaScript: The Only Language Where [] + [] Feels Like a Philosophical Question 😂](https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Favx5x5hcbfmhf3q3mp9q.png)