Topic 1.1
Variables: let, const and var
In one line
A variable is a name that points to a value so you can use it later; declare it with const by default, with let when the value must change, and avoid the old var.
Think of it like this
Labelled storage boxes. You write a label (the name) on a box and put something inside (the value). A let box lets you take the thing out and put something else in. A const box has its label glued to that one box forever. But if the box holds a toy chest, you can still rearrange the toys inside the chest: the glue only fixes which box the label is on, not what happens inside it.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Variable
- A name that points to a value, so the program can use the value again later.
- Declare
- Create a variable with
let,constorvarand a name. - Assign
- Store a value under a name using one
=sign. - Initialise
- Declare a variable and give it its first value in the same line.
- Reassign
- Make an existing variable point to a different value.
- Binding
- The link between a name and a value.
constfixes the link, not the value. - Block
- Code between curly braces
{ }.letandconstlive only inside their block. - Reserved word
- A word the language uses itself, like
iforclass, that can't be a variable name. - camelCase
- Writing names like
totalPrice: first word lowercase, later words start with a capital. - undefined
- The value a variable has when it was declared but not given a value.
Step by step
01Declare and assign
Write the keyword, the name, =, and the value. Read it as "let score be 0". From now on, writing score means "the value stored under score".
let score = 0;
console.log(score); // 002Reassign a let variable
The right side of = is worked out first, using the old value, then the result is stored back. So score = score + 10 reads the 0, adds 10, and stores 10.
score = score + 10;
console.log(score); // 1003const refuses a new value
A const must be initialised and can never point to another value. The error happens when the line runs, so lines before it still run.
const MAX_LIVES = 3;
MAX_LIVES = 5; // TypeError: Assignment to constant variable.04const with an object: the binding is fixed, the contents aren't
user always points to the same object. Changing a property inside that object is allowed. Pointing user at a new object is not.
const user = { name: "Ravi", age: 30 };
user.age = 31; // allowed: same object, changed inside
user = { name: "Meera" }; // TypeError: Assignment to constant variable.05let stays in its block, var leaks out
A let declared inside { } disappears at the closing brace. A var in the same place is still visible after it. This leaking is the main reason var was replaced.
{
let inside = "only in here";
var leaky = "visible everywhere";
}
console.log(leaky); // "visible everywhere"
console.log(inside); // ReferenceError: inside is not defined06Pick good names
A good name says what the value means: cartTotal beats x, isOpen beats flag. Names starting with is, has or can usually hold true/false values.
Try it yourself
- 1
Predict, then run
In the first example, add
score = score * 2;before the last line. Predict the text on the page first, then press Run. - 2
Make the const change
In the second example, change
const maxLivestolet maxLives. Predict the console output before running. Why does the last line now print? - 3
Declare twice with let
In the fourth example, change both
var countlines tolet count. Run it: nothing at all prints, and the console showsUncaught SyntaxError: Identifier 'count' has already been declared. A syntax error stops the whole script before its first line runs.
Code & diagrams
Preview
Console
Nothing logged yet.Expected console output
Start: 0
After a goal: 10
Player: Asha
Declared but not assigned: undefinedThe error stops the script at that line. Lines before it already ran.
Console
(nothing was printed)Expected console output
Lives: 3
Uncaught TypeError: Assignment to constant variable.In a normal script, writing to a frozen object is silently ignored. In strict mode it throws a TypeError instead.
Console
(nothing was printed)Expected console output
{ name: 'Ravi', age: 31 }
Pune`typeof` on a name that doesn't exist gives the string `"undefined"` instead of an error (more in Topic 1.2).
Console
(nothing was printed)Expected console output
I leak out of the block
undefined
count: 2
Is it on window? trueBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Use a name with a typo
In the first example, change console.log("Player:", playerName); to console.log("Player:", playername); (lowercase n).
Break #2
Declare a const without a value
Write const total; and later total = 5;.
Myth vs fact
Myth
const means the value can never change.
Fact
const means the name can never point to another value. If the value is an object or array, its contents can still change. Use Object.freeze to lock an object's own properties.
Myth
let and var are the same thing, let is just newer.
Fact
let is block-scoped, can't be redeclared and can't be used before its line (Topic 3.5). var is function-scoped, can be redeclared and leaks onto window at the top level.
Myth
You should use let everywhere to be safe.
Fact
Prefer const. It prevents accidental reassignment and tells readers the name won't change. Use let only when you reassign.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Top-level
letandconstin a classic script are global but are not properties ofwindow: they live in a separate "declarative environment record" of the global scope. That's whywindow.oldStyleworks forvarbutwindow.newStylewould beundefinedforlet. - ▸
constgives engines no real speed boost in modern JIT compilers (they already see which variables never change). Use it for readability and safety, not performance. - ▸
Object.freezeis shallow. For deep immutability you freeze recursively, or usestructuredClonecopies and immutable update patterns (Topic 15.1). In strict mode, writing to a frozen property throwsTypeError: Cannot assign to read only property. - ▸
Re-declaring a top-level
letin the DevTools console is allowed (Chrome relaxes the rule there for convenience), but in a real script it's a SyntaxError. Don't trust the console to tell you what a script will do.
Remember this
- 1
A variable is a name your program uses to remember a value. Creating one is called declaring it: you write a keyword (
let,constorvar) and a name, likelet score;. Putting a value in is called assigning, and it uses a single=:score = 10;. In JavaScript=means "store this value under this name", not "is equal to" (equality uses===, Topic 1.6). Doing both at once,let score = 10;, is called initialising the variable. A declared variable with no value yet holdsundefined. - 2
let(added in ES2015) makes a variable you can reassign: give it a new value later withscore = score + 5;. Aletvariable lives only inside the block where it was declared. A block is any code between curly braces{ }. Outside that block the name doesn't exist. Declaring the same name twice withletin the same block is a SyntaxError: the browser refuses to run the whole script, before any of it runs. - 3
const(also ES2015) makes a variable that can't be reassigned. You must give it a value straight away (const lives;is a SyntaxError), andlives = 5;later throwsTypeError: Assignment to constant variable.Important:constfixes the binding (the link between the name and the value), not the value itself. Aconstobject or array can still be changed inside:const user = { age: 30 }; user.age = 31;works. To stop changes inside an object, useObject.freeze(user)(which is shallow: objects nested inside it can still change). - 4
varis the original keyword from 1995. It has three habits that cause bugs: it ignores blocks (avardeclared inside{ }is visible outside, becausevaronly respects function boundaries), it lets you declare the same name twice without any error, and at the top level of a script it becomes a property of the globalwindowobject, where it can clash with the browser's own properties (likewindow.name). It is also usable before its declaration line, with the valueundefined(this is hoisting, covered in Topic 3.5). Modern code doesn't usevar; you'll still meet it in old code and in interviews. - 5
Names have rules. A name may contain letters, digits,
_and$, but can't start with a digit (2ndis invalid,secondis fine). Names are case-sensitive:score,ScoreandSCOREare three different variables. You can't use a reserved word, a word the language itself uses, such aslet,const,class,return,iforfunction. By convention JavaScript uses camelCase (totalPrice,isLoggedIn): the first word lowercase, each next word starting with a capital. Fixed settings known before the program runs are often written in UPPER_SNAKE_CASE (MAX_LIVES). - 6
The professional habit: **use
constby default, andletonly when you know the value will be reassigned** (a counter, a running total).consttells the reader "this name won't point anywhere else", which makes code easier to follow. Never assign to a name you didn't declare: in old "sloppy" scripts that silently creates a global variable, and in strict mode (modules, classes, or a file starting with"use strict") it throwsReferenceError: x is not defined.
Explain it without notes
What is the difference between let, const and var?
If const variables can't change, why can you push into a const array?
Why do style guides say "const by default"?
What happens if you assign to a variable you never declared?
Practice
Declare a variable for a shop's name that never changes and one for the number of visitors, which starts at 0. Add 1 visitor twice, then log Hectal Shop has 2 visitors.
Fix this code so it runs: const price = 100; price = price - 20; console.log(price);
Which of these names are valid? firstName, 2ndPlace, _count, $total, class, my-score.
Trade-offs
- ↔
consteverywhere makes code predictable, but forcing it where a value really changes leads to awkward workarounds; uselethonestly for counters and accumulators. - ↔
Object.freezeprotects data from accidental changes but is shallow and adds a small cost; most teams rely on conventions and code review instead, and freeze only shared configuration.
Done when you can
I can declare, assign and reassign variables.
I can choose between
constandletand explain why.I can explain why a
constobject can still change inside.I can list three problems with
var.I know the naming rules and use camelCase.