JavaScript tutorials > JavaScript Basics > Data Types & Variables > What is the difference between var, let, and const?
What is the difference between var, let, and const?
In JavaScript, var
, let
, and const
are keywords used to declare variables. While they serve a similar purpose, there are significant differences in their scope, hoisting, and re-declaration/re-assignment capabilities. Understanding these differences is crucial for writing clean, maintainable, and bug-free JavaScript code.
Basic Syntax & Code Snippets
This code demonstrates the basic syntax for declaring variables using var
, let
, and const
. Each keyword is followed by the variable name and an optional initial value.
// var example
var x = 10;
// let example
let y = 20;
// const example
const z = 30;
Scope: var
Variables declared with var
have function scope. This means they are accessible within the entire function in which they are declared, even if declared inside a block (like an if
statement or a loop). If you declare a var
variable with the same name inside the function, the inner declaration overwrites the outer declaration. This can lead to unexpected behavior if not handled carefully.
function exampleVar() {
var a = 1;
if (true) {
var a = 2; // Overwrites the previous 'a'
console.log("Inside if: " + a); // Output: Inside if: 2
}
console.log("Outside if: " + a); // Output: Outside if: 2
}
exampleVar();
Scope: let
Variables declared with let
have block scope. This means they are only accessible within the block in which they are defined (e.g., inside an if
statement, a for
loop, or a function block). If you declare a let
variable with the same name in an inner block, it creates a new variable that shadows the outer one. The outer variable remains unchanged.
function exampleLet() {
let b = 1;
if (true) {
let b = 2; // Creates a new 'b' in this block
console.log("Inside if: " + b); // Output: Inside if: 2
}
console.log("Outside if: " + b); // Output: Outside if: 1
}
exampleLet();
Scope: const
Variables declared with const
also have block scope, just like let
. They are only accessible within the block they are defined in. Similar to let
, redeclaring const
in an inner block creates a new, shadowed variable.
function exampleConst() {
const c = 1;
if (true) {
const c = 2; // Creates a new 'c' in this block
console.log("Inside if: " + c); // Output: Inside if: 2
}
console.log("Outside if: " + c); // Output: Outside if: 1
}
exampleConst();
Re-declaration and Re-assignment
var
variables can be re-declared and re-assigned. let
variables cannot be re-declared within the same scope but can be re-assigned. const
variables cannot be re-declared or re-assigned after their initial declaration. This means const
variables must be initialized when they are declared.
// var can be re-declared and re-assigned
var d = 5;
var d = 10; // Re-declaration is allowed
d = 15; // Re-assignment is allowed
console.log(d); // Output: 15
// let cannot be re-declared (in the same scope), but can be re-assigned
let e = 5;
// let e = 10; // Error: Identifier 'e' has already been declared
e = 15; // Re-assignment is allowed
console.log(e); // Output: 15
// const cannot be re-declared or re-assigned
const f = 5;
// const f = 10; // Error: Identifier 'f' has already been declared
// f = 15; // Error: Assignment to constant variable
console.log(f); // Output: 5
Hoisting
Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their scope before code execution. var
variables are hoisted and initialized with undefined
. This means you can access them before their declaration in the code, but their value will be undefined
. let
and const
variables are also hoisted, but they are not initialized. Accessing them before their declaration results in a ReferenceError
(Cannot access 'variable' before initialization). This behavior is sometimes referred to as the 'Temporal Dead Zone' (TDZ).
console.log(g); // Output: undefined (hoisted with a default value of undefined)
var g = 5;
//console.log(h); // Error: Cannot access 'h' before initialization
let h = 5;
//console.log(i); // Error: Cannot access 'i' before initialization
const i = 5;
When to use them
const
for variables that should not be re-assigned, such as constants, configuration values, or references to DOM elements. This helps prevent accidental modifications.let
for variables that will be re-assigned, such as loop counters or temporary values.var
in modern JavaScript. Its function scope and hoisting behavior can lead to unexpected bugs.
Best Practices
const
by default, and only use let
if you need to re-assign the variable.var
in modern JavaScript development.
Interview Tip
Be prepared to explain the differences in scope, hoisting, and re-declaration/re-assignment between var
, let
, and const
. You might be asked to provide examples and explain the implications of using each keyword.
Real-Life Use Case Section
Consider a React component. You'd likely use Example:const
for the component's definition itself, and for things like imported functions. You might use let
inside a function to manage a temporary variable while processing some data.
const MyComponent = () => {
const [count, setCount] = React.useState(0);
let newCount = count + 1;
return (
<button onClick={() => setCount(newCount)}>
Clicked {count} times
</button>
);
};
FAQ
-
Why should I avoid using
var
?
var
has function scope, which can lead to unexpected behavior and bugs, especially in larger codebases. It also exhibits hoisting behavior that can be confusing.let
andconst
provide more predictable block scoping, making code easier to understand and maintain. -
What happens if I try to re-assign a
const
variable?
You will get a
TypeError
: Assignment to constant variable. This is becauseconst
variables are intended to hold a constant value that should not be changed after initialization. -
Does
const
mean the value is immutable?
Not necessarily.
const
means that the variable itself cannot be re-assigned to a different value. However, if theconst
variable holds an object or array, the properties or elements of that object or array can still be modified. To make an object truly immutable, you would need to use techniques likeObject.freeze()
.