JavaScript Variables, Bindings, and Scope
Learn how let and const create bindings, how reassignment works, where lexical bindings are scoped, and how values move through runnable JavaScript examples.
Basic
A variable declaration creates a binding: a name that your program can use to reach a value. The important distinction is that
let creates a mutable binding, while
const creates an immutable binding. The value itself may still be mutable when the value is an object; the binding rule is about reassignment.
1. Start with the binding
Read the code, predict the output, then change the starting value and run it. The goal is to see a binding change from one value to another.
let score = 10;
console.log(score);
score = 14;
console.log(score);Output
Ready to run.
2. let and const answer different questions
Use
letwhen the binding must be reassigned. Use
constwhen the binding itself should not be reassigned. This is not a statement that the value is frozen.
const siteName = "Foxipa";
let visits = 1;
visits += 1;
console.log(siteName);
console.log(visits);Quick check
Which declaration matches a binding that must be reassigned later?
count = 0;
count += 1;
3. A declaration is not the same as an assignment
The declaration introduces the binding. A later assignment changes what a mutable binding refers to. Keeping those operations separate makes code easier to read and prepares you for expressions and operators.
let message;
console.log(message); // undefined
message = "Ready";
console.log(message); // "Ready"
Quick check
What does this program print first?
let message;
console.log(message);
4. Names are part of the program design
A good binding name tells the reader what role the value plays. Prefer names that describe the data or state rather than names that merely describe its type.
const learnerName = "Maya";
let completedLessons = 3;
completedLessons += 1;
console.log(`${learnerName} completed ${completedLessons} lessons.`);Use const by default when reassignment is not part of the design.
Use let when the binding really changes during the program.
Choose names that describe meaning, not just implementation details.
Keep declaration and later assignment separate when that makes the state change easier to see.
5. Scope: the binding belongs to its block
Modern lexical declarations are block-scoped. A binding declared inside a pair of braces belongs to that block and is not available after the block ends.
Output
Ready to run.
Quick check
Which statement about the binding declared inside the braces is correct?
{
const secret = "inside";
}
console.log(secret);
6. Template literals use expressions inside ${…}
A template literal is a string literal written with backticks. A substitution inside
${…} evaluates an expression and inserts its result into the resulting string.
const name = "Maya";
let lessons = 3;
console.log(`Hello, ${name}. You have ${lessons} lessons.`);7. Build the idea yourself
Change the runnable score tracker so that the initial score is 20 and the button adds 10. Then add a second button that subtracts 5. Keep the score binding mutable, keep the page label derived from the current score, and run the result.
Authoring rules to remember
Choose const when the binding is not reassigned; choose let when reassignment is required.
Do not describe const as making an object deeply immutable; it prevents rebinding.
Remember that let and const are block-scoped lexical declarations.
Treat template substitutions as expressions whose results become part of the string.
When teaching a new operator or expression later, build on these bindings rather than introducing unrelated syntax at the same time.
Next step
You now have the binding model needed for the next layer: expressions combine values and produce results. Continue to Expressions and Operators after you can explain which names may be reassigned, what scope a binding belongs to, and what value an uninitialized let binding receives.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.