Variables are how you give names to values so you can work with them. JavaScript has three ways to declare variables, but modern code uses only two.
let and const
let declares a variable whose value can change:
let count = 0;
count = 1; // okay — reassigned
count = 2; // okay — reassigned again
const declares a variable whose value cannot be reassigned:
const MAX = 100;
MAX = 50; // TypeError — Assignment to constant variable
The rule in modern JavaScript is simple:
- use
constby default - use
letonly when you know the value needs to change
const name = "Ada"; // will not change
let attempts = 0; // will increment
attempts = attempts + 1;
Why not var
var is the older way to declare variables. It still works but has two problems:
- it ignores block scope —
varinside aniforforleaks into the enclosing function - it hoists to
undefinedinstead of throwing an error when accessed too early
var x = 10;
if (true) {
var x = 20; // redeclares the same variable — no new scope
}
console.log(x); // 20 — the inner assignment overwrote the outer one
With let:
let x = 10;
if (true) {
let x = 20; // new variable, block-scoped
}
console.log(x); // 10 — the outer variable is unchanged
let and const behave predictably. var does not. Modern JavaScript avoids var entirely.
Primitive types
JavaScript has seven primitive types. A primitive is a value that is not an object — it is a single, indivisible unit.
string
Text enclosed in single or double quotes, or backticks for template literals:
let greeting = "Hello";
let name = 'Ada';
let message = `Hello, ${name}`; // template literal with interpolation
number
Integers and decimals. JavaScript uses a single 64-bit floating-point format for all numbers:
let integer = 42;
let decimal = 3.14;
let negative = -7;
There is also Infinity and NaN (not a number, which is itself a number type):
10 / 0 // Infinity
parseInt("abc") // NaN
typeof NaN // "number"
boolean
true or false:
let isActive = true;
let hasPermission = false;
undefined
A variable that has been declared but not assigned a value:
let value;
console.log(value); // undefined
null
An intentional absence of value. It must be assigned explicitly:
let user = null; // intentionally empty
symbol
A unique identifier, rarely used directly in everyday code:
const id = Symbol("unique id");
bigint
Integers too large for the number type to represent precisely:
const huge = 9007199254740991n; // note the trailing n
Checking types
The typeof operator returns the type of a value as a string:
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof Symbol() // "symbol"
typeof 10n // "bigint"
typeof null // "object" — a historical quirk, ignore it
The null result is a well-known historical bug in JavaScript. Use value === null to check for null, not typeof.
What to carry forward
- use
constby default,letwhen reassignment is needed, avoidvar - JavaScript has 7 primitive types: string, number, boolean, undefined, null, symbol, bigint
- primitives are indivisible values — they are not objects
typeofidentifies types but returns"object"fornulldue to a historical bugnullandundefinedboth represent “no value” in most practical code
These types are the building blocks for everything else. The next lesson covers objects and arrays, which are how JavaScript structures data.