JavaScript Core/
Lesson

JavaScript is flexible, sometimes too flexible. When you mix different types in operations, JavaScript doesn't throw errors; it tries to make sense of what you meant by converting values automatically. This automatic conversion is called type coercionWhat is type coercion?JavaScript automatically converting a value from one type to another during an operation, like turning a string into a number for subtraction., and it's responsible for some of JavaScript's most infamous "wat" moments.

Implicit coercion: JavaScript guesses

Imagine asking someone "What's 5 plus 3?" and they answer "53" because they treated your numbers as text. That's essentially what JavaScript does:

// The + operator with strings
console.log("5" + 3);     // "53" (string concatenation)
console.log(5 + "3");     // "53" (string wins)
console.log("5" + "3");   // "53" (both strings)

// But other operators convert to numbers
console.log("5" - 3);     // 2 (numeric subtraction)
console.log("5" * 3);     // 15 (numeric multiplication)
console.log("5" / 3);     // 1.666... (numeric division)
console.log("5" % 3);     // 2 (numeric modulo)

Why the inconsistency? The + operator serves double duty, addition for numbers, concatenation for strings. When one operand is a string, JavaScript assumes you want concatenation. Other arithmetic operators only make sense with numbers, so JavaScript converts strings to numbers.

AI pitfall
AI tools love to generate code that silently relies on implicit coercion. They'll write if (userInput == 42) instead of if (Number(userInput) === 42), or build price calculations directly from form values without converting strings to numbers first. The code "works" in the happy path but breaks with edge cases like "0", empty strings, or null. Never trust AI-generated arithmetic on values that might be strings, always convert explicitly.

Comparison coercion

This is where things get really weird:

console.log("5" == 5);          // true (!!!)
console.log(true == 1);         // true (!!!)
console.log(false == 0);        // true (!!!)
console.log("" == false);       // true (!!!)
console.log(null == undefined); // true (!!!)
console.log([1] == "1");        // true (!!!)

The loose equality operator (==) performs type coercionWhat is type coercion?JavaScript automatically converting a value from one type to another during an operation, like turning a string into a number for subtraction. before comparison. The rules are complex and sometimes surprising, that's why experienced JavaScript developers pretend it doesn't exist.

The null and undefined gotchas

console.log(null == undefined);  // true
console.log(null === undefined); // false

console.log(null == 0);   // false (surprisingly!)
console.log(null >= 0);   // true (coerces null to 0!)

Yes, null >= 0 is true while null == 0 is false. This happens because relational operators (>, <, >=, <=) coerce null to 0, but equality operators treat null as special.

Just use `===` and `!==`
These strict equality operators never coerce. They compare both value AND type. "5" === 5 is false because a string is not a number, even when they look similar.
02

Explicit conversion: You take control

Instead of letting JavaScript guess, tell it exactly what you want:

Converting to numbers

// The Number() function
console.log(Number("42"));      // 42
console.log(Number("42.5"));    // 42.5
console.log(Number(""));        // 0 (empty string becomes 0)
console.log(Number("hello"));   // NaN (Not a Number)
console.log(Number(true));      // 1
console.log(Number(false));     // 0
console.log(Number(null));      // 0
console.log(Number(undefined)); // NaN

Converting to strings

// The String() function
console.log(String(42));        // "42"
console.log(String(true));      // "true"
console.log(String(null));      // "null"
console.log(String(undefined)); // "undefined"
console.log(String([1, 2, 3])); // "1,2,3"

// Alternative: toString() method
console.log((42).toString());   // "42"
console.log(true.toString());   // "true"

Converting to booleans

// The Boolean() function
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(undefined));// false
console.log(Boolean([]));       // true (empty array is truthy!)
console.log(Boolean({}));       // true (empty object is truthy!)
03

Truthy and falsy values

In boolean contexts (like if statements or logical operators), values are coerced to true or false. Knowing which values become which prevents bugs.

The six falsy values

These always become false:

ValueWhy it's falsy
falseThe boolean itself
0Zero
""Empty string
nullIntentional absence
undefinedUninitialized
NaNInvalid number

Everything else is truthy

// These might surprise you
console.log(Boolean("0"));      // true (non-empty string)
console.log(Boolean("false"));  // true (non-empty string)
console.log(Boolean([]));       // true (empty array)
console.log(Boolean({}));       // true (empty object)
console.log(Boolean(function(){})); // true (functions are objects)

Practical truthy/falsyWhat is truthy/falsy?How JavaScript treats non-boolean values in conditions: some values act as false (0, empty string, null, undefined, NaN) and everything else acts as true. patterns

// Check if string has content
const input = "";
if (input) {
  console.log("Has content");
} else {
  console.log("Empty"); // This runs
}

// But be careful with numbers!
const count = 0;
if (count) {
  console.log("Has items");
} else {
  console.log("Empty or zero"); // This runs (0 is falsy!)
}

// Better check for numbers
if (count > 0) {
  console.log("Has items");
}
04

Practical conversion examples

// Form input handling
const userAge = "25";
const age = Number(userAge);

if (age >= 18) {
  console.log("Adult");
}

// Safe conversion with fallback
const priceInput = "abc";
const price = Number(priceInput) || 0;
console.log(price);  // 0 (because NaN || 0 returns 0)

// String concatenation safety
const items = 5;
const message = "You have " + String(items) + " items";
// Or better: `You have ${items} items`
05

Quick reference

ConversionMethodWatch out for
To numberNumber(x)Number("") is 0, Number("hello") is NaN
To stringString(x)String(null) is "null", not ""
To booleanBoolean(x)Boolean([]) is true, Boolean("") is false
Check NaNNumber.isNaN(x)isNaN("hello") is true (coerces first)
Strict compare=== / !==Never coerces, always safe
javascript
// Implicit coercion (often surprising)
console.log("5" + 3);        // "53" (string wins)
console.log("5", 3);        // 2 (number math)
console.log("5" == 5);       // true (coerced equality)
console.log("5" === 5);      // false (strict equality)
console.log(true + true);    // 2 (booleans become 1 + 1)

// Explicit conversion (predictable)
console.log(Number("42"));   // 42
console.log(String(42));     // "42"
console.log(Boolean(1));     // true
console.log(Boolean(0));     // false

// Truthy vs falsy
console.log(Boolean("0"));   // true (non-empty string)
console.log(Boolean([]));    // true (empty array)
console.log(Boolean(""));    // false (empty string)
console.log(Boolean(null));  // false

// Safe form handling
const userInput = "25";
const age = Number(userInput);
if (!isNaN(age)) {
  console.log(`User is ${age} years old`);
}