let vs const vs var
const and let have block scope, while var has function scope. const doesn’t allow reassignment. In new code write const, and let only for values that change.
Side-by-side comparison
#Scope
Reassignment
Redeclaration in the same scope
Referencing before the declaration
Value at declaration
A variable in a loop with a callback
When to use it
Example
#const course = 'JavaScript'
let level = 1
level = level + 1
if (level > 1) {
var visible = 'var is visible outside the block'
let hidden = 'let only exists inside the block'
}
console.log(course, level)
console.log(visible)
console.log(typeof hidden)Definition and usage
#All three keywords declare variables, but they differ in scope, whether they can be reassigned, and how they behave before the declaration. let and const entered the language in ES2015 and have block scope: they exist only inside the curly braces where they were declared. var has function scope, so it reaches beyond if blocks and loops.
const doesn’t let you assign the variable a new value, but it doesn’t freeze the object: you can still add an element to an array declared with const. let allows reassignment. Up to the point of declaration, both sit in what’s called the temporal dead zone, so referencing them earlier throws a ReferenceError. A var declaration is hoisted to the top of the function and holds undefined until the assignment runs.
The practical rule: const by default, let only for values that genuinely change (counters, running totals in a loop), and var not at all. You’ll run into it in older projects and in old forum answers, so it’s worth understanding how it differs.
Syntax
#const name = value
let name = value
var name = valueMore examples
#const skills = ['HTML']
skills.push('CSS')
console.log(skills)
try {
skills = []
} catch (error) {
console.log(error.name)
}You can change the contents of an array or object, just not the assignment itself. Use Object.freeze() to freeze an object.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log('var', i), 0)
}
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log('let', j), 0)
}All the functions from the first loop see the same variable i, which is 3 once the loop finishes. let creates a new variable for every iteration.
try {
console.log(points)
let points = 10
} catch (error) {
console.log(error.name)
}
console.log(bonus)
var bonus = 5Good practices
#- Start with
constand switch toletonly once the editor or linter flags an attempted reassignment. - The ESLint rules
prefer-constandno-varenforce this rule across the whole project. - The block scope of
letandconstapplies to every block:if, loops,try, and standalone curly braces.
Related entries
#- constDeclares a block-scoped constant. A variable like this can’t be assigned a new value.
- letDeclares a block-scoped variable whose value you can change later.
- varDeclares a function-scoped variable. This is the older way, replaced today by let and const.
- forA loop with a counter: initialization, condition, and step. Repeats a block of code while the condition is true.
Spotted a mistake or missing an example? Write to us.