JavaScript has three ways to declare a variable, and choosing the wrong one is one of the most common interview mistakes.
var → function-scoped, hoisted, re-declarable (avoid)
let → block-scoped, not hoisted*, reassignable (default choice)
const → block-scoped, not hoisted*, not reassignable (prefer for values that don't change)
Block scope vs function scope — the most important distinction:
if (true) {
var x = 1; // leaks out of the block!
let y = 2; // stays inside
}
console.log(x); // 1 — var ignores block boundaries
console.log(y); // ReferenceError — let respects them
JavaScript has exactly 7 primitive types. Memorise them — interviewers ask this directly:
| Type | Example | typeof returns |
|---|---|---|
string | "hello" | "string" |
number | 42, NaN, Inf | "number" |
bigint | 9007199254740991n | "bigint" |
boolean | true, false | "boolean" |
undefined | undefined | "undefined" |
symbol | Symbol("id") | "symbol" |
null | null | "object" ← ⚠️ |
Everything else — arrays, functions, dates, regular expressions — is an object at runtime.
const means the binding can't be reassigned — not that the value is immutable:
const nums = [1, 2, 3];
nums.push(4); // ✓ fine — mutating the array, not reassigning the binding
nums = [1, 2, 3, 4]; // ✗ TypeError: Assignment to constant variable
const config = { debug: false };
config.debug = true; // ✓ fine — mutating the object
config = {}; // ✗ TypeError
For true immutability, use Object.freeze() — but note it's shallow.
The next section covers the typeof operator — and its famous exceptions.