JavaScript Type Conversion
JavaScript automatically converts data types in certain situations (implicit coercion). You can also convert types manually (explicit conversion). Understanding both is crucial for avoiding bugs.
Explicit Type Conversion
Use built-in functions to convert between types intentionally:
Converting to String
// String() function
String(123) // "123"
String(3.14) // "3.14"
String(true) // "true"
String(false) // "false"
String(null) // "null"
String(undefined) // "undefined"
String([1, 2, 3]) // "1,2,3"
String({a: 1}) // "[object Object]"
// .toString() method
(123).toString() // "123"
true.toString() // "true"
[1, 2].toString() // "1,2"
// Template literals (implicit)
`Value: ${42}` // "Value: 42"
// Concatenation (implicit)
"" + 42 // "42"Converting to Number
// Number() function
Number("123") // 123
Number("3.14") // 3.14
Number("") // 0 (empty string!)
Number(" ") // 0 (whitespace only!)
Number("123abc") // NaN (strict)
Number(true) // 1
Number(false) // 0
Number(null) // 0
Number(undefined) // NaN
// parseInt() - integers only
parseInt("42") // 42
parseInt("42.9") // 42 (truncates)
parseInt("42px") // 42 (stops at 'p')
parseInt("px42") // NaN (starts with letter)
parseInt("0xFF") // 255 (hex)
parseInt("101", 2) // 5 (binary, radix 2)
// parseFloat() - decimals
parseFloat("3.14") // 3.14
parseFloat("3.14.15") // 3.14 (stops at second dot)
// Unary plus (shorthand)
+"42" // 42
+"" // 0
+true // 1Number("42px") returns NaN (strict). parseInt("42px") returns 42 (lenient). Choose based on your needs. Converting to Boolean
// Boolean() function
Boolean(1) // true
Boolean(0) // false
Boolean(-1) // true (any non-zero)
Boolean("") // false
Boolean("hello") // true
Boolean("false") // true (non-empty string!)
Boolean(null) // false
Boolean(undefined) // false
Boolean(NaN) // false
Boolean([]) // true (empty array!)
Boolean({}) // true (empty object!)
// Double negation (shorthand)
!!1 // true
!!"hello" // true
!!0 // false
!!"" // false
// Falsy values (memorize these!)
// false, 0, -0, 0n, "", null, undefined, NaN[] and objects {} are truthy, not falsy! Only the 8 falsy values evaluate to false. Try It Yourself
Experiment with explicit type conversions:
// Explicit String Conversion
console.log("=== To String ===");
console.log(String(123)); // "123"
console.log(String(true)); // "true"
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
console.log((123).toString()); // "123"
// Explicit Number Conversion
console.log("\n=== To Number ===");
console.log(Number("123")); // 123
console.log(Number("3.14")); // 3.14
console.log(Number("")); // 0
console.log(Number("hello")); // NaN
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
// parseInt and parseFloat
console.log("\n=== Parsing ===");
console.log(parseInt("42px")); // 42
console.log(parseFloat("3.14em")); // 3.14
console.log(parseInt("abc123")); // NaN
// Boolean Conversion
console.log("\n=== To Boolean ===");
console.log(Boolean(1)); // true
console.log(Boolean(0)); // false
console.log(Boolean("hello")); // true
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean([])); // true (empty array!)
console.log(Boolean({})); // true (empty object!)Implicit Type Coercion
JavaScript automatically converts types in certain operations:
// String coercion (+ with string)
"5" + 3 // "53" (number to string)
5 + "3" // "53"
"5" + true // "5true"
// Number coercion (other operators)
"10" - 5 // 5 (string to number)
"10" * "2" // 20
"10" / 2 // 5
"5" - "3" // 2
// Comparison coercion
5 == "5" // true (converts string to number)
0 == false // true (converts false to 0)
null == undefined // true (special case)
"" == false // true (both convert to 0)
// Avoid implicit coercion - use explicit!
Number("5") + 3 // 8 (clear intent)
String(5) + "3" // "53" (clear intent)Number() and String(). See implicit coercion in action:
// String concatenation wins
console.log("=== String Coercion ===");
console.log("5" + 3); // "53"
console.log(3 + "5"); // "35"
console.log("Hello" + 123); // "Hello123"
// Math operators convert to numbers
console.log("\n=== Number Coercion ===");
console.log("10" - 5); // 5
console.log("10" * 2); // 20
console.log("10" / 2); // 5
console.log("5" - "3"); // 2
// Unary plus converts to number
console.log("\n=== Unary Plus ===");
console.log(+"42"); // 42
console.log(+true); // 1
console.log(+false); // 0
console.log(+"hello"); // NaN
// Comparison coercion
console.log("\n=== Comparison ===");
console.log(5 == "5"); // true (loose)
console.log(5 === "5"); // false (strict)
console.log(null == undefined); // true
console.log(null === undefined); // false
// Boolean context
console.log("\n=== Boolean Context ===");
console.log(!!"hello"); // true
console.log(!!0); // false
console.log(!!null); // false
console.log(!![]); // true (empty array is truthy!)Truthy and Falsy Values
Values that evaluate to false in boolean context:
// Falsy values (only 8 of them!)
if (false) {} // falsy
if (0) {} // falsy
if (-0) {} // falsy
if (0n) {} // falsy (BigInt zero)
if ("") {} // falsy
if (null) {} // falsy
if (undefined) {} // falsy
if (NaN) {} // falsy
// Everything else is truthy!
if (true) {} // truthy
if (1) {} // truthy
if ("hello") {} // truthy
if ("false") {} // truthy (it's a non-empty string!)
if ([]) {} // truthy (empty array!)
if ({}) {} // truthy (empty object!)
if (function(){}) {} // truthy
// Common pattern: default values
const name = userInput || "Guest"; // if userInput is falsy
const count = data ?? 0; // if data is null/undefinedConversion Reference
| Value | Boolean | Number | String |
|---|---|---|---|
| false | false | 0 | "false" |
| 0 | false | 0 | "0" |
| "" | false | 0 | "" |
| null | false | 0 | "null" |
| undefined | false | NaN | "undefined" |
| NaN | false | NaN | "NaN" |
| [] | true | 0 | "" |
| {} | true | NaN | "[object Object]" |
Best Practices
=== instead of == to avoid implicit coercion in comparisons. Number(), String(), Boolean() instead of relying on implicit coercion. ?? (nullish coalescing) instead of || when 0 or "" are valid values. Test Your Knowledge
Test Your Knowledge
5 questionsWhat does Number("") return?
What does Boolean([]) return?
What does "5" + 3 return?
What does parseInt("42px") return?
What does null == undefined return?
Practice Exercise
Safe Number Conversion
Create a function that converts various values to numbers with sensible defaults for edge cases.
// Challenge: Create a function that safely converts any value to a number
// Rules:
// - Return the number if input is already a number
// - Parse strings that start with numbers (like "42px")
// - Return 0 for empty strings, null, false
// - Return 1 for true
// - Return NaN for values that can't be converted
function toNumber(value) {
// TODO: Implement safe number conversion
}
// Test cases
console.log(toNumber(42)); // should print 42
console.log(toNumber("123")); // should print 123
console.log(toNumber("42px")); // should print 42
console.log(toNumber("")); // should print 0
console.log(toNumber(null)); // should print 0
console.log(toNumber(true)); // should print 1
console.log(toNumber(false)); // should print 0
console.log(toNumber("hello")); // should print NaN
console.log(toNumber(undefined)); // should print NaN
Frequently Asked Questions
Why does [] == false return true?
With ==, both sides are converted to numbers. [] becomes 0 (via "" first), and false becomes 0. So 0 == 0 is true. This is why you should use ===.
When should I use parseInt vs Number?
Use Number() when you want strict conversion (any invalid character returns NaN). Use parseInt() when parsing strings like "42px" or "100%" where you want to extract the number.
Why is NaN !== NaN?
NaN is the only JavaScript value that is not equal to itself. This is by design (IEEE 754 standard). Use Number.isNaN(x) to check for NaN, not x === NaN.
Summary
JavaScript has two types of type conversion:
- Explicit: Using String(), Number(), Boolean(), parseInt()
- Implicit: Automatic conversion during operations
Key points to remember:
- Only 8 values are falsy: false, 0, -0, 0n, "", null, undefined, NaN
- Empty arrays and objects are truthy
- Use
===to avoid implicit coercion in comparisons - Prefer explicit conversion for clarity