Chapter 3 of 28 · JavaScript for Beginners — Complete Free Tutorial
Variables: let, const & var
Variables are named containers for values. JavaScript has three keywords to declare them — let, const and var — and the differences are not cosmetic: they decide how your code behaves when scopes get interesting. This chapter teaches the modern pair first and explains exactly why var is mostly history.
let: a variable that can change
let score = 10;
score = score + 5; // reassignment is fine
console.log(score); // → 15
let total = score * 2; // new name, new variable
console.log(total); // → 30
const: a binding that cannot be reassigned
const pi = 3.14159;
pi = 3; // ❌ TypeError: Assignment to constant variable.
Important nuance: const freezes the binding, not the value. Objects and arrays stay mutable:
const user = { name: 'Asha' };
user.name = 'Ravi'; // ✅ allowed — mutating the object
console.log(user.name); // → Ravi
user = { name: 'Mira' }; // ❌ TypeError — reassigning the binding
Rule of thumb: start every declaration with const. Switch to let only when you know the value must change (counters, accumulators, reassignment in loops).
var: the legacy keyword
function announce() {
var message = 'Hi'; // function-scoped, not block-scoped
if (true) {
var message = 'Hello'; // same variable — no new scope!
}
console.log(message); // → 'Hello'
}
announce();
var differs from let in three unhelpful ways:
- Function scope — it leaks out of every
{ }block. - Hoisting — declared “upstairs”, so it exists as
undefinedbefore its line runs (see chapter 12). - Implicit globals — assigning without declaring creates a global variable by accident.
In modern code you never need it. You will still read it in older libraries.
let vs var: block scope in action
if (true) {
let a = 1;
var b = 2;
}
console.log(a); // ❌ ReferenceError: a is not defined
console.log(b); // → 2 (b escaped the block 😬)
A “block” is anything inside curly braces — if, for, while bodies. let and const stay inside it; var does not. Full scope mechanics are covered in Scope, Hoisting & Closures.
Naming rules
| Rule | Valid | Invalid |
|---|---|---|
Letters, digits, _, $ | userName2 | user name |
| Cannot start with a digit | _count | 2fast |
| Case-sensitive | score ≠ Score | — |
| Not reserved words | total | class, return |
Use camelCase (totalPrice, isVisible) and names that describe what is stored, not how — minutesLeft, not m.
Declaration, assignment, initialisation
let count; // declaration (value is undefined)
count = 0; // assignment
let items = []; // declaration + initialisation in one line
const-first workflow
const API_URL = 'https://api.example.com'; // never reassigned → const
let attempts = 0; // incremented → let
const results = []; // array never reassigned → const
results.push('ok'); // mutation is fine
Expected output: fewer bugs and clearer intent — a reader instantly knows which bindings vary.
Common mistakes
const“can’t change” myth — you cannot reassign it, but object contents still change; freeze withObject.freeze()if you truly need immutability.- Mixing
varinto new code — it silently breaks block scoping. - Declaring the same variable twice —
letthrowsSyntaxError: Identifier has already been declared. - Vague names —
dataandtemptell your future self nothing.
Practice checklist
- Write a snippet where
constreassignment throws — read the exact error message. - Compare
letandvarinside anifblock and observe which escapes. - Refactor an old snippet: every
var→const, then only the true mutables →let.
Variables hold values — but what kinds of values exist? Next: Data Types & Type Coercion.
Frequently Asked Questions
JavaScript is the programming language of the web. It adds behaviour to pages: responding to clicks and input, validating forms, fetching data from APIs, updating the DOM without reloading, and much more. It also runs on servers (Node.js), in desktop and mobile apps, and in build tooling.
They are unrelated languages that share a similar name for historical marketing reasons. Java is a statically-typed compiled language; JavaScript is a dynamically-typed interpreted language designed for the browser. Knowing one does not imply knowledge of the other.
Helpful but not mandatory — HTML gives you the structure JavaScript manipulates and CSS the styling it toggles. If you know basic tags, classes and selectors, you have enough to start; the DOM chapters assume only that much.
Use const by default and let when the value must change. Avoid var entirely in modern code: it is function-scoped instead of block-scoped, hoists differently, and can create accidental globals. This course uses const and let throughout.
The Document Object Model is the browser’s in-memory tree of objects representing your HTML. JavaScript reads and modifies that tree — selecting elements, changing text, adding nodes, attaching event listeners — and the browser re-renders the page to match.
== compares after converting types (so 5 == "5" is true), while === requires the same value AND the same type (5 === "5" is false). Loose equality has famously confusing rules — use === and !== everywhere unless you have a specific reason not to.
JavaScript is single-threaded, so long-running work (timers, fetches, events) is handled by the browser and its callbacks are queued. The event loop moves queued callbacks onto the call stack only when it is empty, with promise callbacks (microtasks) taking priority over timers. It is why asynchronous code never freezes the page.
A Promise is an object representing a future value — pending, fulfilled or rejected — that can be chained and combined (Promise.all). async/await is syntax sugar over promises that lets asynchronous code read top-to-bottom with ordinary try/catch error handling.
Yes. Frameworks are built on exactly these fundamentals — components are functions, state is your variable discipline, effects are events, rendering is DOM work. Developers who learn vanilla first understand what the framework is doing and debug far faster.
Type out the examples instead of copying, build small end-to-end projects (expense tracker, weather app, quiz), handle every UI state (loading, empty, success, error), and revisit fundamentals while reading real code. Consistency beats volume — a little most days outpaces occasional marathons.