Welcome back! 👋 In the previous lesson, you learned about JavaScript's data types. Now, let's dive deeper into one of JavaScript's most important (and sometimes confusing) features: Type Conversion and Type Coercion.
Understanding how JavaScript converts between types is crucial for writing bug-free code and avoiding unexpected behavior. Let's master this essential concept!
What is Type Conversion?
Type conversion (also called type casting) is the process of converting a value from one data type to another.
JavaScript has two types of conversion:
1. Explicit Conversion (Type Casting)
When you manually convert a value from one type to another.
let str = "123";
let num = Number(str); // YOU explicitly convert string to number
console.log(num); // 123
console.log(typeof num); // "number"2. Implicit Conversion (Type Coercion)
When JavaScript automatically converts a value from one type to another.
let result = "5" + 3; // JavaScript automatically converts 3 to "3"
console.log(result); // "53" (string)
let result2 = "5" - 3; // JavaScript automatically converts "5" to 5
console.log(result2); // 2 (number)Why Does Type Conversion Matter?
JavaScript is dynamically typed and weakly typed, meaning it tries to be helpful by automatically converting types. This can lead to:
Good things:
- More flexible code
- Less verbose syntax
- Quick prototyping
Bad things:
- Unexpected behavior
- Hard-to-find bugs
- Confusion for beginners
Example of potential confusion:
console.log("5" + 3); // "53" (string concatenation)
console.log("5" - 3); // 2 (numeric subtraction)
console.log("5" * 3); // 15 (numeric multiplication)
// Why different behavior? Type coercion rules!Explicit Type Conversion (Type Casting)
Let's learn how to manually convert between types.
Converting to String
Method 1: String() Function (Recommended)
// Numbers to strings
console.log(String(123)); // "123"
console.log(String(3.14)); // "3.14"
console.log(String(-42)); // "-42"
// Booleans to strings
console.log(String(true)); // "true"
console.log(String(false)); // "false"
// null and undefined to strings
console.log(String(null)); // "null"
console.log(String(undefined)); // "undefined"
// Objects and arrays
console.log(String([1, 2, 3])); // "1,2,3"
console.log(String({a: 1})); // "[object Object]"Method 2: .toString() Method
let num = 123;
console.log(num.toString()); // "123"
let bool = true;
console.log(bool.toString()); // "true"
let arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3"
// ⚠️ Cannot use on null or undefined
// null.toString(); // ❌ TypeError
// undefined.toString(); // ❌ TypeErrorMethod 3: Template Literals (Implicit but Explicit)
let num = 123;
console.log(`${num}`); // "123"
let bool = true;
console.log(`${bool}`); // "true"
// Very readable for string interpolation
let age = 30;
console.log(`I am ${age} years old`); // "I am 30 years old"Method 4: Concatenation with Empty String
let num = 123;
console.log(num + ""); // "123"
let bool = true;
console.log(bool + ""); // "true"
// Simple but less explicitWhen to Use Each Method:
String()- Most explicit and safe (works with null/undefined).toString()- When you know value is not null/undefined- Template literals - When building strings with variables
+ ""- Quick conversion (but less clear)
Converting to Number
Method 1: Number() Function (Recommended)
// Strings to numbers
console.log(Number("123")); // 123
console.log(Number("3.14")); // 3.14
console.log(Number(" 42 ")); // 42 (trims whitespace)
// Booleans to numbers
console.log(Number(true)); // 1
console.log(Number(false)); // 0
// null and undefined to numbers
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
// Invalid conversions
console.log(Number("abc")); // NaN
console.log(Number("12abc")); // NaN
console.log(Number("")); // 0 (empty string becomes 0!)Method 2: parseInt() and parseFloat()
// parseInt() - Converts to integer
console.log(parseInt("123")); // 123
console.log(parseInt("123.45")); // 123 (removes decimal)
console.log(parseInt("123abc")); // 123 (stops at non-digit)
console.log(parseInt("abc123")); // NaN (starts with non-digit)
console.log(parseInt(" 42 ")); // 42 (trims whitespace)
// parseFloat() - Converts to decimal
console.log(parseFloat("3.14")); // 3.14
console.log(parseFloat("3.14abc")); // 3.14 (stops at non-digit)
console.log(parseFloat("123")); // 123
// parseInt() with radix (base)
console.log(parseInt("10", 10)); // 10 (decimal)
console.log(parseInt("10", 2)); // 2 (binary)
console.log(parseInt("10", 16)); // 16 (hexadecimal)
console.log(parseInt("FF", 16)); // 255 (hex to decimal)
// Always specify radix to avoid confusion!
console.log(parseInt("08")); // 8 (but could be interpreted as octal in old JS)
console.log(parseInt("08", 10)); // 8 (explicitly decimal)Method 3: Unary Plus Operator (+)
let str = "123";
console.log(+str); // 123
console.log(+"3.14"); // 3.14
console.log(+true); // 1
console.log(+false); // 0
console.log(+null); // 0
console.log(+undefined); // NaN
console.log(+""); // 0
console.log(+"abc"); // NaN
// Quick and concise but less explicitMethod 4: Mathematical Operations
let str = "123";
console.log(str * 1); // 123
console.log(str - 0); // 123
console.log(str / 1); // 123
// Works but not recommended (unclear intent)Comparison: Number() vs parseInt() vs parseFloat()
let value = "123.45abc";
console.log(Number(value)); // NaN (strict - fails on invalid)
console.log(parseInt(value)); // 123 (lenient - parses what it can)
console.log(parseFloat(value)); // 123.45 (lenient - parses what it can)
// Another example
let value2 = " 42 ";
console.log(Number(value2)); // 42 (handles whitespace)
console.log(parseInt(value2)); // 42 (handles whitespace)When to Use Each Method:
Number()- When you want strict conversion (all or nothing)parseInt()- When extracting integers from stringsparseFloat()- When extracting decimals from strings- Unary
+- Quick conversion when you know format is valid
Converting to Boolean
Method 1: Boolean() Function (Recommended)
// Falsy values (convert to false)
console.log(Boolean(false)); // false
console.log(Boolean(0)); // 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 values (convert to true)
console.log(Boolean(true)); // true
console.log(Boolean(1)); // true
console.log(Boolean(-1)); // true
console.log(Boolean("hello")); // true
console.log(Boolean("0")); // true (string "0" is truthy!)
console.log(Boolean(" ")); // true (space is truthy!)
console.log(Boolean([])); // true (empty array is truthy!)
console.log(Boolean({})); // true (empty object is truthy!)
console.log(Boolean(function(){})); // trueMethod 2: Double NOT Operator (!!)
console.log(!!1); // true
console.log(!!0); // false
console.log(!!"hello"); // true
console.log(!!""); // false
console.log(!!null); // false
console.log(!!undefined); // false
// How it works:
// !value - converts to boolean and inverts
// !!value - converts to boolean and inverts twice (back to original truth value)
let value = "hello";
console.log(!value); // false (inverted)
console.log(!!value); // true (double inverted = original)Method 3: Conditional Context (Implicit)
let value = "hello";
// Automatically converts to boolean in conditions
if (value) {
console.log("Truthy!"); // Executes
}
// Ternary operator
let result = value ? "yes" : "no"; // "yes"
// Logical operators
console.log(value && "success"); // "success"
console.log(0 || "default"); // "default"Complete Truthy/Falsy Reference:
Falsy Values (Only 7!):
false // The boolean false
0 // Zero
-0 // Negative zero
0n // BigInt zero
"" // Empty string
null // Null value
undefined // Undefined value
NaN // Not a NumberEverything else is truthy, including:
true // Boolean true
1, -1, 42 // Non-zero numbers
"0", "false" // Non-empty strings (even "0" and "false"!)
" " // String with just space
[] // Empty array
{} // Empty object
function(){} // Functions
Infinity // Infinity
new Date() // Date objectsImplicit Type Coercion
Now let's explore how JavaScript automatically converts types in different operations.
String Coercion (+ Operator)
When + is used with a string, everything becomes a string:
// String + anything = String (concatenation)
console.log("Hello" + " World"); // "Hello World"
console.log("5" + 3); // "53"
console.log("5" + true); // "5true"
console.log("5" + null); // "5null"
console.log("5" + undefined); // "5undefined"
console.log("5" + [1, 2]); // "51,2"
console.log("5" + {a: 1}); // "5[object Object]"
// Number + String = String (order matters!)
console.log(5 + "3"); // "53"
console.log(5 + 3 + "2"); // "82" (5+3=8, then "8"+"2"="82")
console.log("2" + 5 + 3); // "253" ("2"+5="25", "25"+3="253")
// Multiple additions (left to right)
console.log(1 + 2 + "3"); // "33" (1+2=3, 3+"3"="33")
console.log("1" + 2 + 3); // "123" ("1"+2="12", "12"+3="123")Rule: If any operand is a string with +, the result is a string.
Numeric Coercion (-, *, /, %)
Other arithmetic operators convert to numbers:
// String - Number = Number (subtraction)
console.log("5" - 3); // 2
console.log("10" - "3"); // 7
console.log("5" - true); // 4 (true becomes 1)
console.log("5" - false); // 5 (false becomes 0)
console.log("5" - null); // 5 (null becomes 0)
console.log("5" - undefined); // NaN (undefined becomes NaN)
// String * Number = Number (multiplication)
console.log("5" * 3); // 15
console.log("10" * "2"); // 20
console.log("5" * true); // 5 (true becomes 1)
// String / Number = Number (division)
console.log("10" / 2); // 5
console.log("10" / "2"); // 5
// String % Number = Number (modulus)
console.log("10" % 3); // 1
console.log("10" % "3"); // 1
// Invalid conversions result in NaN
console.log("abc" - 3); // NaN
console.log("abc" * 2); // NaN
console.log("5" - "abc"); // NaNRule: -, *, /, % always try to convert operands to numbers.
Boolean Coercion (Logical Context)
In logical contexts, values are coerced to boolean:
// if statements
if ("hello") {
console.log("Truthy!"); // Executes
}
if (0) {
console.log("Won't execute"); // Doesn't execute
}
// Logical NOT (!)
console.log(!1); // false (1 is truthy)
console.log(!0); // true (0 is falsy)
console.log(!"hello"); // false
console.log(!""); // true
// Logical AND (&&)
console.log(true && "result"); // "result" (returns last truthy)
console.log(false && "result"); // false (returns first falsy)
console.log(1 && 2 && 3); // 3 (all truthy, returns last)
console.log(1 && 0 && 3); // 0 (returns first falsy)
// Logical OR (||)
console.log(false || "default"); // "default" (returns first truthy)
console.log(true || "default"); // true (returns first truthy)
console.log(0 || null || "value"); // "value" (first truthy)
// Ternary operator
let age = 18;
let status = age >= 18 ? "adult" : "minor"; // "adult"Short-circuit Evaluation:
// && returns first falsy or last truthy
console.log(0 && "never checked"); // 0 (stops at first falsy)
console.log(1 && 2 && 3); // 3 (all truthy, returns last)
// || returns first truthy or last falsy
console.log(1 || "never checked"); // 1 (stops at first truthy)
console.log(0 || null || undefined); // undefined (all falsy, returns last)
// Practical use: Default values
let userName = "";
let displayName = userName || "Guest"; // "Guest" (userName is falsy)
let count = 0;
let display = count || 10; // 10 (be careful with 0!)Comparison Coercion
Loose Equality (==)
== performs type coercion before comparison:
// Number comparisons
console.log(5 == "5"); // true (string "5" converts to number 5)
console.log(0 == false); // true (false converts to 0)
console.log(1 == true); // true (true converts to 1)
// null and undefined are special
console.log(null == undefined); // true (special rule)
console.log(null == 0); // false (doesn't convert to 0)
console.log(undefined == 0); // false
// Empty values
console.log("" == 0); // true (empty string converts to 0)
console.log("0" == 0); // true (string "0" converts to 0)
console.log(false == ""); // true (both convert to 0)
// Arrays and objects
console.log([] == 0); // true (empty array converts to 0)
console.log([] == ""); // true (empty array converts to "")
console.log([1] == 1); // true (array converts to "1", then to 1)
// Confusing cases!
console.log("0" == false); // true (both convert to 0)
console.log("" == false); // true (both convert to 0)
console.log(" " == false); // false (" " is truthy but doesn't equal false!)Strict Equality (===)
=== does NOT perform type coercion:
// Must be same type AND same value
console.log(5 === "5"); // false (different types)
console.log(0 === false); // false (different types)
console.log(1 === true); // false (different types)
console.log(null === undefined); // false (different types)
// Same type and value
console.log(5 === 5); // true
console.log("5" === "5"); // true
console.log(true === true); // true
// Always use === unless you have a specific reason to use ==Comparison Operator Coercion Rules:
// < > <= >= convert to numbers
console.log("10" > 5); // true ("10" converts to 10)
console.log("2" > "12"); // true (string comparison! "2" > "1")
console.log("2" > 12); // false (number comparison! 2 < 12)
console.log("abc" > 5); // false (NaN comparisons are always false)
// String comparison is lexicographical (dictionary order)
console.log("apple" < "banana"); // true
console.log("10" < "9"); // true ("1" < "9" in string comparison)
console.log(10 < 9); // false (numeric comparison)Visual Summary:
== (Loose Equality) === (Strict Equality)
──────────────────── ─────────────────────
5 == "5" → true 5 === "5" → false
0 == false → true 0 === false → false
"" == 0 → true "" === 0 → false
null == undefined → true null === undefined → false
USE === ALMOST ALWAYS! Use == only when specifically neededCommon Type Coercion Pitfalls
Pitfall 1: Addition vs Concatenation
// Problem: Confusing + operator
let a = "5";
let b = 3;
console.log(a + b); // "53" (concatenation, not addition!)
// Solution: Explicit conversion
console.log(Number(a) + b); // 8 (addition)
console.log(+a + b); // 8 (addition)Pitfall 2: Truthy vs True
// Problem: Truthy doesn't mean === true
console.log("0" == true); // false
console.log(Boolean("0")); // true (truthy)
console.log([] == true); // false
console.log(Boolean([])); // true (truthy)
// Solution: Use explicit boolean conversion or strict comparison
if (Boolean("0")) { // ✅ Explicit
console.log("String '0' is truthy");
}
if ("0") { // ✅ Also fine (implicit truthy check)
console.log("String '0' is truthy");
}Pitfall 3: Empty String Converts to 0
// Problem: Empty string is falsy but converts to 0
console.log(Number("")); // 0
console.log("" == 0); // true
console.log(Boolean("")); // false
// This can cause issues
function calculateTotal(input) {
return Number(input) + 10;
}
console.log(calculateTotal("")); // 10 (intended?)
console.log(calculateTotal("5")); // 15
// Solution: Check for empty string explicitly
function calculateTotal(input) {
if (input === "") {
return 0;
}
return Number(input) + 10;
}Pitfall 4: NaN Comparisons
// Problem: NaN is not equal to anything, including itself
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
let result = "abc" * 2;
console.log(result == NaN); // false (can't check this way!)
// Solution: Use isNaN() or Number.isNaN()
console.log(isNaN(result)); // true
console.log(Number.isNaN(result)); // true (more reliable)Pitfall 5: null vs undefined
// Problem: They're similar but different
console.log(null == undefined); // true (loose equality)
console.log(null === undefined); // false (strict equality)
console.log(null == 0); // false (doesn't convert)
console.log(null < 1); // true (converts to 0)
console.log(null > -1); // true (converts to 0)
// Solution: Always use === for null/undefined checks
if (value === null) { // ✅ Explicit
console.log("Value is null");
}
if (value === undefined) { // ✅ Explicit
console.log("Value is undefined");
}
// Or check for both
if (value == null) { // ✅ Only case where == is useful
console.log("Value is null or undefined");
}Pitfall 6: Array to Primitive Conversion
// Problem: Arrays convert in surprising ways
console.log([1, 2, 3] + [4, 5, 6]); // "1,2,34,5,6" (string concatenation!)
console.log([] + []); // "" (empty string)
console.log([] + {}); // "[object Object]"
console.log({} + []); // "[object Object]" or 0 (depends on context!)
// Arrays convert to strings via .join(",")
console.log([1, 2, 3].toString()); // "1,2,3"
console.log(String([1, 2, 3])); // "1,2,3"
// Solution: Be explicit about what you want
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
console.log([...arr1, ...arr2]); // [1, 2, 3, 4, 5, 6] (concatenate arrays)Type Conversion Best Practices
1. Always Use Strict Equality (===)
// ❌ Bad - unpredictable
if (value == 0) {
console.log("Is zero?");
}
// ✅ Good - explicit
if (value === 0) {
console.log("Is exactly zero");
}
// Exception: Checking for null/undefined
if (value == null) { // ✅ OK - checks both null and undefined
console.log("Is null or undefined");
}2. Be Explicit with Type Conversions
// ❌ Bad - relying on coercion
let total = "5" + 3; // "53"
let result = "5" - 3; // 2
// ✅ Good - explicit conversion
let total = Number("5") + 3; // 8
let result = Number("5") - 3; // 2
// ✅ Good - clear intent
let str = String(123);
let num = Number("123");
let bool = Boolean(1);3. Validate Input Types
// ❌ Bad - assuming type
function add(a, b) {
return a + b; // Could concatenate strings!
}
// ✅ Good - validate types
function add(a, b) {
if (typeof a !== "number" || typeof b !== "number") {
throw new TypeError("Both arguments must be numbers");
}
return a + b;
}
// ✅ Good - convert and validate
function add(a, b) {
const numA = Number(a);
const numB = Number(b);
if (isNaN(numA) || isNaN(numB)) {
throw new TypeError("Cannot convert arguments to numbers");
}
return numA + numB;
}4. Use Template Literals for String Building
// ❌ Bad - confusing with +
let message = "Total: " + price + " (" + quantity + " items)";
// ✅ Good - clear intent
let message = `Total: ${price} (${quantity} items)`;5. Handle Edge Cases
// ❌ Bad - doesn't handle edge cases
function parseUserInput(input) {
return Number(input);
}
console.log(parseUserInput("")); // 0 (is this intended?)
console.log(parseUserInput("abc")); // NaN (how to handle?)
console.log(parseUserInput(null)); // 0 (is this intended?)
// ✅ Good - explicit handling
function parseUserInput(input) {
// Handle empty/null/undefined
if (input === "" || input == null) {
return null; // or throw error, or return default
}
const num = Number(input);
// Handle NaN
if (isNaN(num)) {
throw new Error(`Invalid number: ${input}`);
}
return num;
}6. Use isNaN() Correctly
// ❌ Bad - isNaN coerces to number first
console.log(isNaN("abc")); // true (expected)
console.log(isNaN("123")); // false (expected)
console.log(isNaN("123abc")); // true (expected)
console.log(isNaN({})); // true (unexpected?)
// ✅ Better - Number.isNaN() doesn't coerce
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN("abc")); // false (not actually NaN)
console.log(Number.isNaN(123)); // false
// ✅ Best - validate type first
function isValidNumber(value) {
return typeof value === "number" && !isNaN(value) && isFinite(value);
}
console.log(isValidNumber(123)); // true
console.log(isValidNumber("123")); // false (string, not number)
console.log(isValidNumber(NaN)); // false
console.log(isValidNumber(Infinity)); // falsePractical Examples
Example 1: Form Input Validation
function validateAge(input) {
// Handle empty input
if (input === "" || input == null) {
return { valid: false, error: "Age is required" };
}
// Convert to number
const age = Number(input);
// Check if valid number
if (isNaN(age)) {
return { valid: false, error: "Age must be a number" };
}
// Check range
if (age < 0 || age > 150) {
return { valid: false, error: "Age must be between 0 and 150" };
}
// Check if integer
if (!Number.isInteger(age)) {
return { valid: false, error: "Age must be a whole number" };
}
return { valid: true, value: age };
}
// Test cases
console.log(validateAge("25")); // { valid: true, value: 25 }
console.log(validateAge("")); // { valid: false, error: "Age is required" }
console.log(validateAge("abc")); // { valid: false, error: "Age must be a number" }
console.log(validateAge("25.5")); // { valid: false, error: "Age must be a whole number" }
console.log(validateAge("-5")); // { valid: false, error: "Age must be between 0 and 150" }Example 2: Safe Mathematical Operations
function safeDivide(a, b) {
// Convert to numbers
const numA = Number(a);
const numB = Number(b);
// Validate conversions
if (isNaN(numA) || isNaN(numB)) {
return null; // or throw error
}
// Check for division by zero
if (numB === 0) {
return null; // or return Infinity, or throw error
}
return numA / numB;
}
console.log(safeDivide(10, 2)); // 5
console.log(safeDivide("10", "2")); // 5 (converts strings)
console.log(safeDivide(10, 0)); // null (division by zero)
console.log(safeDivide("abc", 2)); // null (invalid number)Example 3: Default Values with Proper Handling
// ❌ Bad - 0 and "" are falsy
function greet(name) {
name = name || "Guest";
return `Hello, ${name}!`;
}
console.log(greet("John")); // "Hello, John!"
console.log(greet("")); // "Hello, Guest!" (intended?)
console.log(greet(0)); // "Hello, Guest!" (unexpected!)
// ✅ Good - explicit null/undefined check
function greet(name) {
name = (name !== undefined && name !== null) ? name : "Guest";
return `Hello, ${name}!`;
}
// ✅ Better - using nullish coalescing (ES2020)
function greet(name) {
name = name ?? "Guest"; // Only replaces null/undefined
return `Hello, ${name}!`;
}
console.log(greet("John")); // "Hello, John!"
console.log(greet("")); // "Hello, !" (empty string preserved)
console.log(greet(0)); // "Hello, 0!" (0 preserved)
console.log(greet(null)); // "Hello, Guest!"
console.log(greet(undefined));// "Hello, Guest!"Type Conversion Cheat Sheet
Quick Reference Table
| From | To String | To Number | To Boolean |
|---|---|---|---|
"123" | "123" | 123 | true |
"123.45" | "123.45" | 123.45 | true |
"abc" | "abc" | NaN | true |
"" | "" | 0 | false |
"0" | "0" | 0 | true |
0 | "0" | 0 | false |
1 | "1" | 1 | true |
-1 | "-1" | -1 | true |
true | "true" | 1 | true |
false | "false" | 0 | false |
null | "null" | 0 | false |
undefined | "undefined" | NaN | false |
[] | "" | 0 | true |
[1,2,3] | "1,2,3" | NaN | true |
{} | "[object Object]" | NaN | true |
NaN | "NaN" | NaN | false |
Operator Coercion Summary
// + with string → string concatenation
"5" + 3 → "53"
5 + "3" → "53"
// - * / % → numeric operation
"5" - 3 → 2
"5" * 3 → 15
"10" / "2" → 5
"10" % 3 → 1
// == → coerces types
5 == "5" → true
0 == false → true
null == undefined → true
// === → no coercion
5 === "5" → false
0 === false → false
null === undefined → false
// if, while, for → boolean coercion
if ("hello") → true
if (0) → false
if ([]) → truePractice Exercise
Create a file called type-conversion-practice.js:
// Type Conversion Practice
// Exercise 1: Create a function that safely adds two values
function safeAdd(a, b) {
// TODO: Convert to numbers, validate, and add
// Return null if conversion fails
}
// Test cases
console.log(safeAdd(5, 3)); // Should be 8
console.log(safeAdd("5", "3")); // Should be 8
console.log(safeAdd("5", 3)); // Should be 8
console.log(safeAdd("abc", 3)); // Should be null
console.log(safeAdd(null, 5)); // Should be null
// Exercise 2: Create a function that checks if a value is "empty"
function isEmpty(value) {
// TODO: Return true for: null, undefined, "", [], {}
// Return false for everything else
}
// Test cases
console.log(isEmpty(null)); // Should be true
console.log(isEmpty(undefined)); // Should be true
console.log(isEmpty("")); // Should be true
console.log(isEmpty([])); // Should be true
console.log(isEmpty({})); // Should be true
console.log(isEmpty(0)); // Should be false
console.log(isEmpty(false)); // Should be false
console.log(isEmpty("hello")); // Should be false
// Exercise 3: Parse user input with proper error handling
function parseUserNumber(input) {
// TODO: Convert input to number
// Return object: { success: true, value: number } or { success: false, error: string }
}
// Test cases
console.log(parseUserNumber("123")); // { success: true, value: 123 }
console.log(parseUserNumber("123.45")); // { success: true, value: 123.45 }
console.log(parseUserNumber("")); // { success: false, error: "Empty input" }
console.log(parseUserNumber("abc")); // { success: false, error: "Invalid number" }
console.log(parseUserNumber(null)); // { success: false, error: "Null or undefined" }Solutions will be provided in the next lesson!
Key Takeaways
Congratulations! You now understand type conversion and coercion in JavaScript. Here's what you learned:
✅ Type Conversion - Manual conversion between types
- String(): Convert to string
- Number(): Convert to number
- Boolean(): Convert to boolean
- parseInt()/parseFloat(): Parse numbers from strings
✅ Type Coercion - Automatic conversion by JavaScript
+with strings → concatenation-,*,/,%→ numeric operation- Comparisons and logical operators → boolean coercion
✅ Truthy/Falsy Values
- Only 7 falsy values:
false,0,-0,0n,"",null,undefined,NaN - Everything else is truthy
✅ Comparison Operators
==performs type coercion (avoid)===does not coerce (use this!)
✅ Best Practices
- Always use
===instead of== - Be explicit with type conversions
- Validate input types
- Handle edge cases (null, undefined, NaN)
- Use
Number.isNaN()instead ofisNaN()
✅ Common Pitfalls
"5" + 3="53"(concatenation)"5" - 3=2(numeric)- Empty string converts to
0 - Empty array/object are truthy
NaN !== NaN
What's Next?
Excellent work! 🎉 You now have a solid understanding of type conversion and coercion.
In the next lesson, we'll explore Operators and Expressions where you'll learn:
- Arithmetic operators (
+,-,*,/,%,**) - Assignment operators (
=,+=,-=, etc.) - Comparison operators (
==,===,!=,!==,<,>,<=,>=) - Logical operators (
&&,||,!) - Operator precedence and associativity
- Advanced operator patterns
Understanding type conversion is essential for mastering operators!