JavaScript 101: Implicit Type Coercion
tl;dr Javascript automatically converts some types into others behind your back. Like a well meaning friend who “fixes” your dating profile without telling you.
Prerequisites
- Understanding of data types in Javascript
- A browser console (F12, you know the drill)
- An appreciation for chaos
- A llama. They’re surprisingly unfazed by type coercion
Lets break down the name. “Implicit” means something thats always there, baked in. “Coercion” means forcing something to change. Put them together in a programming context and you get: Javascript will silently convert your types whether you like it or not.
When writing programs, its important to know how to compare values to each other. By doing this we can control an applications flow. We know that Javascript has types, but how does it compare each type to another value of a different type? Or a value of the same type? This is where implicit type coercion comes in. And where your debugging sessions get significantly longer.
String Coercion
Consider the following situation:
const a = 10;
const b = "20";
console.log(a + b); // "1020"
Ten plus twenty is one thousand and twenty. Obviously.
Remember that the + operator in Javascript is used for adding not just numbers but strings. So when a number meets a string, Javascript panics and just smooshes them together like a toddler with playdough. The number gets converted into a string. Its a major gotcha and the source of approximately 47% of all Javascript memes.

A clearer example would be to explicitly add a number to a string:
const a = 456;
const b = "javascript";
console.log(a + b); // "456javascript"
But does it work the other way?
const a = 10;
const b = "5";
console.log(a - b); // 5
Wait, what? Now it DOES do maths? The - operator doesnt work on strings, so Javascript converts the string to a number first and then does the subtraction. The + operator concatenates. The - operator does maths. Consistency is not Javascripts strong suit.
const a = 456;
const b = "javascript";
console.log(a - b); // NaN
We get NaN this time because Javascript tried to convert the string “javascript” into a number. It could not. It gave up. NaN stands for “Not a Number” but honestly it might as well stand for “Not gonna happen”.
Boolean Coercion
To understand Boolean coercion you need to understand truthy and falsy values. In Javascript, any value deemed truthy will be converted to true and falsy values converted to false. Simple enough in theory. In practice its a minefield.
We can use the Boolean object to check what Javascript thinks of our values:
Boolean() // false
Boolean("") // false
Boolean(2) // true
Boolean(null) // false
Boolean(0) // false
Boolean(0n) // false
Boolean(undefined) // false
Boolean("a string") // true
Boolean({}) // true
Boolean([]) // true
Yes, an empty array is truthy. An empty object is truthy. An empty string is falsy. Zero is falsy. The string “0” is truthy. The string “false” is truthy. I dont make the rules and I certainly dont agree with them.
You can test this yourself with a quick ternary:
const x = 0;
Boolean(x) ? "true" : "false" // "false"
Try swapping 0 for different values and watch Javascript make increasingly questionable decisions.
Knowing how Javascript evaluates truthy and falsy values helps us determine an applications logic flow. Every if statement you write is secretly doing Boolean coercion under the hood.
Logical Operators
Javascript ships with three logical operators: || (OR), && (AND) and ! (NOT).
Heres the thing that trips people up. Logical operators dont return true or false. They return one of the operands. But because Javascript treats things like non null strings as truthy, we can still use them in conditions and they work as expected. Most of the time.
OR (||) returns the first truthy value it finds. If nothing is truthy, it returns the last value.
AND (&&) returns the first falsy value it finds. If everything is truthy, it returns the last value.
NOT (!) returns false if the operand is truthy, true if the operand is falsy. The only one that actually returns a boolean. How refreshing.
const x = 2340;
const y = "A string";
const z = undefined;
console.log(x || y); // 2340 (first value is truthy, returns it)
console.log(x || z); // 2340 (first value is truthy, returns it)
console.log(x && y); // "A string" (both truthy, returns the last)
console.log(x && z); // undefined (second value is falsy, returns it)
This is why you see patterns like const name = user.name || "Anonymous" everywhere. If user.name is falsy (empty string, null, undefined) it falls back to “Anonymous”. Handy. Until someone’s name is actually the number zero. Then youve got problems.
Equality Coercion
When comparing two values its important to know how Javascript actually handles the comparison. This is where things get properly unhinged.
When using == (double equals), Javascript doesnt just compare the values. It converts them first, THEN compares. Like a translator who paraphrases everything before passing it on. Sure the message gets across but something is always lost.
const a = 3;
const b = "3";
console.log(a == b); // true
Javascript looked at the number 3 and the string “3”, converted one to match the other, and said “yeah those are the same”. Technically correct. The worst kind of correct.
Equality coercion does NOT take place when using the triple equals === operator:
const a = 3;
const b = "3";
console.log(a === b); // false
Triple equals checks both the type AND the value. No conversion. No funny business. This is why every linter, style guide, and senior developer will tell you to use === everywhere. Its just safer. Think of == as checking if two people look similar, and === as checking their dental records.

Further Reading
- MDN: Type Coercion
- MDN: Equality Comparisons
- JavaScript Equality Table (prepare yourself)