2.3 Type Conversion (Type Coercion)
What is Type Conversion?
In JavaScript, type conversion happens in two ways:
- Explicit Conversion: Developer intentionally converts types
- Implicit Coercion: JavaScript engine automatically converts types
Explicit Type Conversion
Converting to Number
console.log(Number("42")); // 42
console.log(Number("")); // 0
console.log(Number("42abc")); // NaN
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
// parseInt() / parseFloat()
console.log(parseInt("42px")); // 42 (extracts number part)
console.log(parseFloat("3.14px")); // 3.14
console.log(parseInt("0xFF", 16)); // 255 (hex parsing)
// Unary + operator
console.log(+"42"); // 42
console.log(+"abc"); // NaN
Converting to String
console.log(String(42)); // "42"
console.log(String(true)); // "true"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
// toString() method
console.log((255).toString(16)); // "ff" (hex string)
console.log((10).toString(2)); // "1010" (binary string)
// Template literal (most readable)
const num = 42;
const str = `${num}`; // "42"
Converting to Boolean
// Falsy values:
console.log(Boolean(false)); // false
console.log(Boolean(0)); // false
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
// Truthy (everything else):
console.log(Boolean("0")); // true (!)
console.log(Boolean([])); // true (!)
console.log(Boolean({})); // true (!)
// Double negation !! for boolean conversion
console.log(!!0); // false
console.log(!!"hello"); // true
Implicit Type Coercion Pitfalls
+ Operator: Addition vs String Concatenation
// Number + Number = Number
console.log(1 + 2); // 3
// Number + String = String (concatenation!)
console.log(1 + "2"); // "12"
console.log("1" + 2); // "12"
// Famous traps
console.log([] + []); // "" (empty string)
console.log([] + {}); // "[object Object]"
console.log("5" + 3); // "53" (!)
console.log("5" - 3); // 2 (arithmetic converts to number)
console.log(true + true); // 2 (1 + 1)
-, *, / Operators: Always Convert to Number
console.log("10" - 5); // 5
console.log("10" * 2); // 20
console.log(true - 1); // 0 (true → 1)
console.log(null - 1); // -1 (null → 0)
console.log(undefined - 1); // NaN
== vs === (Loose vs Strict Equality)
Strict Equality ===
Both type and value must be identical.
console.log(1 === 1); // true
console.log(1 === "1"); // false (different types)
console.log(null === undefined); // false
console.log(NaN === NaN); // false (!)
Loose Equality ==
Compares after type coercion.
console.log(1 == "1"); // true ("1" → 1)
console.log(0 == ""); // true ("" → 0)
console.log(null == undefined); // true (special case)
console.log(null == false); // false (!)
console.log([] == false); // true ([] → "" → 0, false → 0)
console.log("" == false); // true
Recommendation: Always use === and avoid ==.
Safe Type Conversion Patterns
// Safe number conversion
function toNumber(value) {
const num = Number(value);
return Number.isNaN(num) ? 0 : num; // Default 0 if NaN
}
console.log(toNumber("42")); // 42
console.log(toNumber("abc")); // 0 (default instead of NaN)
// Safe string conversion
function toString(value) {
if (value === null || value === undefined) return '';
return String(value);
}
Pro Tips
Express Type Conversions Explicitly
// Bad: relying on implicit conversion
const count = "5" - 0; // 5 (unclear intent)
const str = value + ""; // string conversion (idiomatic but unclear)
// Good: explicit conversion
const count2 = Number("5"); // clear
const str2 = String(value); // clear
const bool2 = Boolean(value); // clear