JavaScript is dynamically typed - variables can hold any type, and types are checked at runtime, not compile time. Understanding types and coercion prevents subtle bugs.
| Type | Category | Example | typeof |
|---|---|---|---|
string | Primitive | "hello" | "string" |
number | Primitive | 42, 3.14, NaN | "number" |
bigint | Primitive | 9007199254740991n | "bigint" |
boolean | Primitive | true, false | "boolean" |
undefined | Primitive | undefined | "undefined" |
null | Primitive | null | "object" ⚠️ |
symbol | Primitive | Symbol("id") | "symbol" |
object | Reference | {}, [], function(){} | "object" |
typeof null
typeof null returns "object" - a famous bug from 1995 never fixed for backward compatibility.
1const single = 'Hello';2const double = "Hello";34// Template literals (backticks) - most powerful5const name = "World";6const greeting = `Hello, ${name}!`; // "Hello, World!"78// Multi-line9const multiline = `10Line 111Line 212`;1314console.log("JavaScript".length); // 10
1const integer = 42;2const decimal = 3.14;3const scientific = 2.5e6; // 2,500,00045// Special values6console.log(Infinity);7console.log(NaN);8console.log(0.1 + 0.2); // 0.300000000000000049console.log(0.1 + 0.2 === 0.3); // false!
Floating Point
0.1 + 0.2 !== 0.3 is how IEEE 754 works in every language. For precision, multiply to integers first: (0.1 * 10 + 0.2 * 10) / 10 === 0.3.
1const isLoggedIn = true;2const hasPermission = false;3console.log(5 > 3); // true4console.log(10 === 20); // false
1// undefined = declared but not assigned2let x;3console.log(x); // undefined45// null = intentionally empty6let user = null;7console.log(user); // null89console.log(null == undefined); // true (loose)10console.log(null === undefined); // false (strict)
When to Use Which
Use null to intentionally say "no value". Let undefined happen naturally for unassigned variables.
1console.log(typeof "hello"); // "string"2console.log(typeof 42); // "number"3console.log(typeof true); // "boolean"4console.log(typeof undefined); // "undefined"5console.log(typeof null); // "object" ⚠️6console.log(typeof {}); // "object"7console.log(typeof []); // "object"8console.log(typeof function(){}); // "function"910// Better array check11console.log(Array.isArray([])); // true
Coercion is JavaScript automatically converting values between types.
1// + with a string converts everything to string2console.log("5" + 3); // "53"3console.log("Hello" + 42); // "Hello42"4console.log("" + true); // "true"56// Explicit7console.log(String(42)); // "42"
1// Math operators (except +) convert to numbers2console.log("6" - 2); // 43console.log("6" * "3"); // 184console.log(true + 1); // 25console.log(null + 5); // 567// Explicit8console.log(Number("42")); // 429console.log(Number("hello")); // NaN10console.log(Number(true)); // 111console.log(Number("")); // 012console.log(Number(undefined)); // NaN
1// The 8 FALSY values:2Boolean(false); // false3Boolean(0); // false4Boolean(""); // false5Boolean(null); // false6Boolean(undefined); // false7Boolean(NaN); // false8Boolean(-0); // false9Boolean(0n); // false1011// Everything else is TRUTHY:12Boolean("hello"); // true13Boolean(42); // true14Boolean([]); // true ← empty array is truthy!15Boolean({}); // true ← empty object is truthy!16Boolean("0"); // true ← string "0" is truthy!
Common Gotcha
Empty arrays [] and objects {} are truthy. Check emptiness with arr.length === 0.
1// == performs type coercion2console.log(5 == "5"); // true3console.log(0 == false); // true4console.log("" == 0); // true56// === checks type AND value (no coercion)7console.log(5 === "5"); // false8console.log(0 === false); // false9console.log("" === 0); // false
Always Use ===
Use strict equality (===) everywhere. The only exception: value == null conveniently checks both null and undefined.
1function validateAge(input) {2const age = Number(input);34if (Number.isNaN(age)) return "Enter a valid number";5if (age < 0 || age > 150) return "Age must be 0-150";6if (!Number.isInteger(age)) return "Must be a whole number";78return "Valid age: " + age;9}1011console.log(validateAge("25")); // "Valid age: 25"12console.log(validateAge("abc")); // "Enter a valid number"13console.log(validateAge("25.5")); // "Must be a whole number"
Now that you understand data types and coercion, let's learn about operators - calculations, comparisons, and logical combinations.