Skip to content
Commitpedia
Log in Join & edit

let, const and var: variables and scope in JavaScript

Use const by default, let when a value must change, and avoid var. The difference is about scope: where a variable is visible and when it exists.

Edit history of let, const and var: variables and scope in JavaScript: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
2 min

JavaScript has three keywords for declaring variables. Modern code uses const for almost everything, let when you really need to reassign, and var only in old code you have not rewritten yet.

The short rule

  • const: the name cannot be pointed at a new value. Use it by default.
  • let: the name can be reassigned, for example a counter or a value built up in a loop.
  • var: the pre-2015 keyword. It ignores block scope and is hoisted in a surprising way.

const does not mean frozen

const protects the binding, not the value. You cannot write user = otherUser, but you can still change properties of the object it points to.

const user = { name: "Ada" };
user.name = "Grace";   // fine: the object is mutable
console.log(user.name); // "Grace"

const limit = 10;
limit = 20; // TypeError: Assignment to constant variable.

If you need a value that truly cannot change, use Object.freeze() (shallow) or keep the data immutable by convention and create new objects instead of editing old ones.

Block scope versus function scope

let and const are block scoped: they exist only inside the nearest pair of curly braces, such as an if body or a loop. var is function scoped: it leaks out of blocks and is shared by the whole function.

The classic place this bites is a loop that schedules work for later:

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log("var:", i), 0);
}
// var: 3, var: 3, var: 3  (one shared i)

for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log("let:", j), 0);
}
// let: 0, let: 1, let: 2  (a fresh j per iteration)

With let, each loop iteration gets its own copy of j, so every callback sees the value from its own round. With var, all callbacks share one variable that has already reached 3 by the time they run.

Hoisting and the temporal dead zone

All three declarations are registered when their scope starts, which is called hoisting. The difference is what happens if you touch the name before the declaration line:

console.log(a); // undefined: var is hoisted and pre-filled
var a = 5;

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 5;

The gap between the start of the block and the let/const line is called the temporal dead zone. It turns a silent undefined bug into a loud error, which is one of the reasons let and const are safer.

Other differences worth knowing

  • Redeclaring the same name with let or const in one scope is a SyntaxError; var allows it silently.
  • A top-level var in a classic browser script becomes a property of window; let and const do not.
  • Inside ES modules every top-level declaration is private to the module, whichever keyword you use.

Practical habits

  1. Start every declaration with const.
  2. Switch to let only when the linter or the code tells you that you reassign it.
  3. When editing old code, replacing var with let is usually safe, but check for code that reads the variable outside the block where it was declared.
  4. Turn on the ESLint rules no-var and prefer-const so the habit is enforced for you.

See also

  • 0017 JavaScript array methods cheat sheet: map, filter, reduce and friends A quick reference for the array methods you use every day, with what each one returns and whether it changes the original… Beginner · Reference · Any system Article Basics 15 Oct 2026
  • 0025 Regular expressions cheat sheet (JavaScript flavor) The regex syntax you actually use, from character classes and quantifiers to groups, lookarounds and flags, with the JavaScript methods that apply… Beginner · Reference · Any system Article Basics · Basics 15 Oct 2026
  • 0026 Fix: TypeError: Cannot read properties of undefined (reading ‘x’) You tried to read a property from a value that is undefined or null. Find which value is missing, then guard it… Beginner · Fix · Any system Article Basics · Common errors 15 Oct 2026

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. commitpedia-admin +3,136 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?