Type Coercion
The Overly Helpful Translator
LinkedIn Hook
"5" + 3returns"53"."5" - 3returns2.[] + []returns"".{} + []returns0.Most devs call this "weird JavaScript." It isn't. It's an algorithm — written down in the ECMAScript spec — and once you know
ToPrimitive,ToNumber, andToString, every single one of those results becomes predictable.Type coercion is where JavaScript plays translator. Sometimes it's helpful. Sometimes it turns a bug into a silent wrong answer.
In this lesson you'll learn the difference between explicit and implicit coercion, the three abstract operations the spec uses, why
+behaves differently from-, and how to decode expressions like{} + []step by step.If an interviewer asks "walk me through why
[] + {}is a string but{} + []is0," after this lesson you'll answer without hesitation.Read the full lesson -> [link]
#JavaScript #TypeCoercion #InterviewPrep #ECMAScript #Frontend #CodingInterview #WebDevelopment
What You'll Learn
- The difference between explicit and implicit coercion — and when each kicks in
- The three spec-level abstract operations:
ToPrimitive,ToNumber,ToBoolean - How to decode tricky expressions like
[] + [],[] + {}, and{} + []step by step
JavaScript, The Overly Helpful Translator
Think of JavaScript as an overly helpful translator. When you speak French to someone who only understands English, JS doesn't throw an error — it silently translates your French into English, sometimes getting the meaning right, sometimes hilariously wrong.
Explicit Coercion — You're in Control
When you intentionally convert a value, it's explicit coercion:
// To Number
Number("42"); // 42
Number("hello"); // NaN
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number(""); // 0
Number(" "); // 0 -- whitespace-only strings become 0!
// To String
String(42); // "42"
String(true); // "true"
String(null); // "null"
String(undefined); // "undefined"
String([1, 2, 3]); // "1,2,3"
String({}); // "[object Object]"
// To Boolean
Boolean(0); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean(1); // true
Boolean("hello"); // true
Boolean([]); // true -- empty array is truthy!
Boolean({}); // true -- empty object is truthy!
Implicit Coercion — JS Does It Behind the Scenes
JavaScript automatically coerces types in certain operations:
// The + operator: if ONE side is a string, it concatenates
"5" + 3; // "53" -- number 3 becomes "3"
"5" + true; // "5true"
"5" + null; // "5null"
"5" + undefined; // "5undefined"
// The -, *, / operators: ALWAYS convert to number
"5" - 3; // 2
"5" * "3"; // 15
"6" / "2"; // 3
true + true; // 2 (1 + 1)
true + false; // 1 (1 + 0)
// Unary + converts to number
+"42"; // 42
+true; // 1
+false; // 0
+""; // 0
+null; // 0
+undefined; // NaN
The Abstract Operations (ECMAScript Spec)
Behind every coercion is one of these internal algorithms:
ToPrimitive: Converts objects to primitives. Calls valueOf() first (for numbers), then toString(). For strings, it calls toString() first, then valueOf().
// How ToPrimitive works on objects
const obj = {
valueOf() { return 42; },
toString() { return "hello"; }
};
// Numeric context -- valueOf() is called first
obj + 0; // 42 (valueOf returned 42)
obj * 2; // 84
// String context -- toString() is called first
`${obj}`; // "hello"
String(obj); // "hello"
ToNumber: The rules:
// ToNumber conversion table:
// undefined -> NaN
// null -> 0
// true -> 1
// false -> 0
// "" -> 0
// " " -> 0 (whitespace trimmed, empty = 0)
// "123" -> 123
// "12.5" -> 12.5
// "hello" -> NaN
// [] -> 0 (ToPrimitive -> "" -> ToNumber -> 0)
// [1] -> 1 (ToPrimitive -> "1" -> ToNumber -> 1)
// [1,2] -> NaN (ToPrimitive -> "1,2" -> ToNumber -> NaN)
ToBoolean: Simply checks if the value is in the falsy list (covered in Lesson 8.4).
Tricky Coercion Examples
// Why does [] + [] equal ""?
// Step 1: ToPrimitive([]) -> [].toString() -> ""
// Step 2: "" + "" -> ""
[] + []; // ""
// Why does [] + {} equal "[object Object]"?
// Step 1: ToPrimitive([]) -> ""
// Step 2: ToPrimitive({}) -> "[object Object]"
// Step 3: "" + "[object Object]" -> "[object Object]"
[] + {}; // "[object Object]"
// Why does {} + [] equal 0?
// The {} at the START of a statement is parsed as an empty block, not an object!
// So it becomes: + [] -> + "" -> 0
{} + []; // 0 (in console; in expression context it's "[object Object]")
// Grouping forces it to be an expression:
({} + []); // "[object Object]"
Common Mistakes
- Thinking
+always means addition — if either operand is a string (or becomes one viaToPrimitive),+concatenates instead of adding. - Using
parseInt(str)without a radix — always pass10for base-10 numbers. Some legacy engines interpret a leading0as octal. - Forgetting that
Number("")andNumber(" ")both return0, notNaN. If you're validating numeric input, check the string first.
Interview Questions
Q: What is the difference between implicit and explicit coercion?
Explicit coercion is when the developer intentionally converts a type using functions like
Number(),String(), orBoolean(). Implicit coercion happens automatically when JavaScript encounters operators or contexts that expect a different type -- like"5" + 3converting 3 to"3".
Q: Why does "5" + 3 produce "53" but "5" - 3 produces 2?
The
+operator is overloaded -- when either operand is a string, it does string concatenation. The-operator only works with numbers, so it converts both operands to numbers first.
Q: Explain {} + [] vs [] + {}.
{} + []in a statement context: the{}is parsed as an empty block, leaving+ []which is+""which is0.[] + {}always evaluates as an expression:ToPrimitive([])is"",ToPrimitive({})is"[object Object]", so the result is"[object Object]".
Q: What does ToPrimitive do?
ToPrimitiveis the spec-level algorithm that converts an object to a primitive based on a hint ("number","string", or"default"). Under thenumberhint it callsvalueOf()first, then falls back totoString(). Under thestringhint it triestoString()first, thenvalueOf().
Q: What is the result of [] + []? Why?
"".ToPrimitive([])returns""(the result of[].toString()), so the expression becomes"" + ""which is"".
Q: What is type coercion?
Type coercion is the automatic or manual conversion of a value from one type to another — for example converting a string to a number, or a boolean to a string. JavaScript performs coercion implicitly in many operators, and explicitly via
Number(),String(),Boolean(), and similar conversion functions.
Quick Reference — Cheat Sheet
TYPE COERCION -- QUICK MAP
Explicit (you call it):
Number(x) String(x) Boolean(x)
+x (unary) `${x}` !!x
Implicit (operator triggers it):
+ with string -> concatenation ("5" + 3 = "53")
- * / % -> ToNumber both ("5" - 3 = 2)
if/while/?: -> ToBoolean
== -> see Lesson 8.3
${x} -> ToString
Abstract operations:
ToPrimitive(obj, hint)
hint "number" -> valueOf then toString
hint "string" -> toString then valueOf
hint "default"-> usually valueOf then toString
ToNumber: "" -> 0, " " -> 0, null -> 0, undefined -> NaN
ToBoolean: only 8 falsy values, everything else truthy
Previous: Primitive vs Reference -> Sticky Notes vs Business Cards Next: Equality Operators -> The Strict vs Lenient Librarian
This is Lesson 8.2 of the JavaScript Interview Prep Course — 14 chapters, 87 lessons.