Skip to main content
Advertisement

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
Advertisement