A variable is a named box for a value. You create one with const
(won't be reassigned) or let (will be):
const birthYear = 2004; // can never be reassigned
let age = 22; // can be reassigned
age = 23; // fine
// const age = 25; // TypeError: Assignment to constant variablePrefer const by default and reach for let only when you know the value
changes. Avoid var — it predates block scope and leaks out of {} blocks
in surprising ways (you'll see a famous example in the loops chapter).
Names can contain letters, digits, _ and $, but not spaces, and can't
start with a digit. Convention is camelCase.
The primitive types
| Type | Examples | Notes |
|---|---|---|
string |
"hello", 'hi', `hey` |
Text, quotes of any style |
number |
42, 3.14, -7 |
One type for ints and decimals |
boolean |
true, false |
Logic |
undefined |
— | Declared but never assigned |
null |
— | Deliberately "nothing" |
bigint |
9007199254740991n |
Huge integers |
symbol |
Symbol("id") |
Unique identifiers |
Everything else — arrays, objects, functions — is an object.
Use typeof to ask any value its type:
Strings and template literals
Backtick template literals (`) embed values with ${...} and span
multiple lines:
Handy string methods: .length, .toUpperCase(), .toLowerCase(),
.includes("x"), .slice(0, 3), .trim(), .split(","),
.replace("a", "b"). Try them in the editor above.
Numbers
10 + 3 // 13 10 - 3 // 7
10 * 3 // 30 10 / 3 // 3.3333...
10 % 3 // 1 remainder — even/odd checks love this
10 ** 3 // 1000 exponent
0.1 + 0.2 // 0.30000000000000004 (!) floats everywhere
Math.round(0.1 + 0.2 * 10) / 10; // round when displaying
NaN // "Not a Number" — result of bad math: "x" * 3Conversions and coercion
Convert explicitly with Number(), String(), Boolean(). Mixing types
without converting (coercion) produces the classic surprises:
"5" * 2 // 10 — * forces numeric math
"5" + 2 // "52" — + prefers concatenation if either side is a string
Number("42") + 8 // 50
Number("abc") // NaNBecause of this, always compare with === (checks type AND value),
never == (which converts first):
5 == "5" // true — converted! avoid ==
5 === "5" // false — different typesTwo modern helpers you'll meet again in the async chapter:
user?.address?.city // optional chaining: undefined instead of a crash
count ?? 0 // nullish coalescing: fallback ONLY for null/undefinedKnowledge Check
4 questions — test your understanding
What happens with: const x = 1; x = 2;
What does typeof [1, 2] return?
What is the result of "5" * 2?
Why prefer === over ==?
Next: Loops & Control Flow