Which JavaScript Keyword Declares a Variable in Code
Discover which JavaScript keyword declares a variable and how let, var, and const differ in scope, mutability, and hoisting. Guidance for reliable code.

Variable declaration keyword in JavaScript is a keyword used to declare a variable such as let, var, or const. These keywords differ in scope, mutability, and hoisting behavior.
What variable declaration means in JavaScript
In JavaScript, declaring a variable means creating a named storage location that your program can read from and write to. The declaration also establishes the scope and mutability rules that govern how that binding behaves. Modern JavaScript emphasizes explicit declarations with let and const, while var remains from earlier codebases. A declaration binds a name to a value, allowing your code to evolve as the program runs. Understanding when and how to declare variables improves readability and reduces bugs arising from implicit globals or unintended reassignments.
Key ideas:
- A binding is a named reference to a value stored in memory.
- The scope determines where the binding is accessible.
- Mutability defines whether the value or the binding can be changed.
- Hoisting affects when a binding is created during code execution.
The three keywords: var, let, and const
JavaScript provides three keywords to declare variables, each with its own semantics:
- var: Function-scoped, hoisted, and can be redeclared. It is the legacy form and can lead to unexpected behavior in blocks.
- let: Block-scoped, not hoisted in the same way as var, and cannot be redeclared in the same scope. It is suitable for variables that change.
- const: Block-scoped, binding cannot be reassigned, but the contents of objects or arrays can be mutated. Use for constants and for bindings that should not be reassigned.
Practical takeaway: prefer const by default, use let when you need to reassign, and reserve var for legacy code interoperability. Example:
let x = 5;
x = 10; // allowed
const y = 20;
// y = 25; // not allowed
var z = 3; // legacy styling, avoid in new codeScope and hoisting explained
Scope defines where a binding is accessible. var is function-scoped, which means the binding is accessible throughout the entire function it is declared in, even before the line of declaration due to hoisting. Let and const are block-scoped, so they exist only within the closest pair of braces. TDZ (temporal dead zone) means you cannot access a let or const binding before its declaration, leading to a ReferenceError if you touch it early.
Hoisting is the process by which declarations are moved to the top of their containing scope. Var declarations are hoisted and initialized with undefined, whereas let and const are hoisted but not initialized, so any access before initialization results in an error.
Illustration:
- Inside a loop, let creates a new binding for each iteration.
- Using var inside a loop shares the same binding across iterations, which can cause bugs.
When to use each keyword in real world code
A practical rule is to use const by default for values that do not need to be reassigned. When a value must change over time, replace const with let. Reserve var only for maintaining older codebases or when you explicitly rely on function-scoped behavior. In modern modules and libraries, let and const provide clearer intent and fewer surprises.
Examples:
- const MAX_USERS = 100; // does not change
- let currentUser = null; // will be assigned later
- var legacyValue = 1; // legacy code, avoid if possible
Common pitfalls and best practices
Common pitfalls include inadvertently creating global bindings by omitting a keyword, confusing hoisting with runtime timing, and mutating a binding declared with const. Best practices:
- Start with const for all bindings, switch to let when reassignment is needed.
- Avoid var to reduce accidental global leakage and hoisting quirks.
- Use meaningful names and keep declarations close to their first usage to improve readability.
- Be mindful of TDZ when accessing let or const before initialization.
Following these habits leads to clearer, more maintainable JavaScript code.
Examples: compare snippets side by side
Compare the same logic written with var, let, and const to see how scoping affects behavior:
function demoVar() {
if (true) {
var v = 1;
}
return v; // 1 because var is function-scoped
}
function demoLet() {
if (true) {
let l = 1;
}
// console.log(l); // ReferenceError
return typeof l;
}
function demoConst() {
const c = { value: 10 };
c.value = 20; // allowed: object properties can mutate
// c = { value: 30 }; // not allowed: binding cannot be reassigned
return c.value;
}These examples illustrate how scope and mutability play out in practice.
Beyond variables: const objects and arrays
Declaring an object or array with const prevents reassigning the binding, but it does not make the object immutable. You can still mutate properties or push new items. If you need true immutability, you must adopt patterns such as Object.freeze or use immutable data structures. In practice, prefer const for references and rely on careful code structure to avoid unintended mutations. For complex state, consider functional patterns that minimize side effects and provide predictable updates.
Performance and maintainability implications
Variable declaration choices influence readability and maintainability more than raw performance. Using const by default communicates intent clearly and reduces accidental reassignments. Let is appropriate for values that change, making loops and conditionals easier to reason about. Consistent use of block-scoped declarations helps prevent bugs, especially in larger modules or teams. Across modern JavaScript, adopting let and const aligns with best practices and improves code quality.
Questions & Answers
What is the difference between var and let in JavaScript?
Var is function-scoped and hoisted with an initial value of undefined. Let is block-scoped and not initialized until declaration, which prevents access before use. In practice, let provides safer scoping for variables inside blocks.
Var is function-scoped and hoisted; let is block-scoped and not initialized until declared, which reduces bugs from early access.
Can I reassign a const variable after declaring it?
You cannot reassign the binding of a const variable. However, if the value is an object or array, you can mutate its contents. To protect your data, avoid reassigning the reference itself.
No, you cannot reassign a const binding. You can mutate the contents of an object though.
Why is block scope important for let and const?
Block scope confines a binding to the nearest surrounding curly braces. This prevents leakage into outer scopes and helps maintain predictable logic within loops and conditionals.
Block scope keeps bindings inside the braces, avoiding unintended access from outside.
Should I always use const in modern JavaScript?
Use const by default to express intent that a binding should not be reassigned. Switch to let only when you know the value must change. This reduces bugs and improves readability.
Yes, start with const and switch to let only when you need reassignment.
What happens if I declare a variable without a keyword?
Declaring without a keyword creates an implicit global, which can leak into other parts of your program and cause hard-to-trace bugs. Always use let, const, or var to declare variables explicitly.
Omitting the keyword makes a global variable, which is risky. Always declare with let, const, or var.
Do let and const have hoisting like var?
Let and const are hoisted but not initialized. Accessing them before declaration results in a ReferenceError due to the temporal dead zone.
Let and const exist in the TDZ until declared, so early access errors occur.
What to Remember
- Start with const by default to signal immutability of bindings
- Use let for values that will be reassigned
- Avoid var to reduce hoisting and scope surprises
- Understand block scope and TDZ for predictable behavior
- Mutating objects declared with const is allowed, but reassigning the binding is not