Differences in Variable Declarations
Understanding how variables are declared and how scope (valid scope) works in JavaScript is essential for effective JavaScript development.
This article provides a clear comparison of the three variable declaration statements—var, let, and const—so you can easily grasp their differences at a glance
Three Types of Variable Declarations
In JavaScript, defining (or setting) a variable for the first time is referred to as "declaring a variable." To declare a variable, you must follow JavaScript's rules and use a variable declaration statement
There isn't just one type of variable declaration—JavaScript provides three types. They are:
varletconst
These three types give developers the flexibility to choose the most appropriate declaration based on code convenience, stability, collision prevention, and avoiding unexpected behavior.
Understanding the features and differences of each variable declaration is crucial for effective JavaScript development.
This article compares var, let, and const in terms of initialization, scope (valid scope), redeclaration and reassignment, and hoisting, so you can quickly see which declaration is appropriate in each situation. Finally, we will discuss the importance of variable declaration and scope in JavaScript.
Initialization
In JavaScript, the process of assigning a value when a variable is declared is called initialization.
| Comparison Item | var |
let |
const |
|---|---|---|---|
| Initialization | Optional | Optional | Required |
| If Not Initialized | JavaScript engine automatically assigns the initial value undefined when referenced. |
JavaScript engine automatically assigns the initial value undefined when referenced. |
Error occurs |
Variables declared with var or let can be assigned a value at declaration or left uninitialized. If no value is assigned, the JavaScript engine automatically assigns undefined as the initial value when the variable is referenced.
In contrast, const must be initialized at the time of declaration. Failing to assign a value will result in an error.
Examples
var
var a = 10;
console.log(a); // Output: 10
var b;
console.log(b); // Output: undefined
let
let a = 10;
console.log(a); // Output: 10
let b;
console.log(b); // Output: undefined
const
const declaration - must be initialized
const age = 30;
const declaration - will throw an error if no initial value is assigned
const age; // Uncaught SyntaxError: Missing initializer in const declaration
Scope
In JavaScript, scope (valid scope) refers to the region or context where a variable or function can be accessed.
| Comparison Item | var |
let |
const |
|---|---|---|---|
| Scope | Global scope or function scope | Global scope or block ({}) scope |
Global scope or block ({}) scope |
var
Variables declared with var have either global scope or function scope:
- A variable declared with
varoutside a function has global scope and is accessible throughout the entire code. - A variable declared with
varinside a function has function scope and is accessible only within that function and its inner functions. - All blocks (
{}) such asiforforstatements do not affect the scope of avarvariable.
In short, a var variable declared outside a function is accessible globally, while one declared inside a function is only accessible within that function.
let, const
Variables declared with let or const have either global scope or block ({}) scope:
- A variable declared with
letorconstoutside a block has global scope and is accessible throughout the code. - A variable declared with
letorconstinside a block has block scope and is accessible only within that block and its inner blocks.
In short, a let or const variable declared outside a block is accessible globally, while one declared inside a block is only accessible within that block.
Meaning of a Block ({})
In JavaScript, a block refers to a section of code enclosed in curly braces {}.
Common examples include:
if () { // if block
// ...
} else { // else block
// ...
}
function exampleFn() { // function block
// ...
}
{ // standalone block (rarely used)
let temp = 10; // temp is only valid within this block
}
for () { // for block
// ...
}
However, even without curly braces, a single statement after if or for is conceptually considered part of a block, but it is not an actual block. Therefore, you cannot declare a variable with let or const there.
Examples
var
/* Global scope */
var globalVar = "Global variable"; // Accessible throughout the code
function exampleFunction() {
/* Function scope */
var functionVar = "Function variable"; // Accessible throughout the function
if (true) {
var blockVar = "Block variable"; // Declared in if block, but accessible throughout the function
console.log(functionVar); // Output: "Function variable"
console.log(blockVar); // Output: "Block variable"
}
// Check if blockVar is accessible outside if block
console.log(blockVar); // Output: "Block variable"
}
exampleFunction();
console.log(globalVar); // Output: "Global variable"
console.log(functionVar); // ReferenceError: functionVar is not defined
let
/* Global scope */
let globalVar = "Global variable"; // Accessible in the top-level block of this file or script
function exampleFunction() {
/* Function block scope */
let functionVar = "Function block variable"; // Accessible within the function block
if (true) {
let innerBlockVar = "If block variable";
console.log(functionVar); // Output: "Function block variable"
console.log(innerBlockVar); // Output: "If block variable"
}
// Cannot access innerBlockVar outside if block
// console.log(innerBlockVar); // ReferenceError: innerBlockVar is not defined
}
if (true) {
let ifBlockVar = "If block variable";
console.log(ifBlockVar); // Output: "If block variable"
}
exampleFunction();
console.log(globalVar); // Output: "Global variable"
// console.log(functionVar); // ReferenceError: functionVar is not defined
// console.log(ifBlockVar); // ReferenceError: ifBlockVar is not defined
const
/* Global scope */
const globalVar = "Global variable"; // Accessible in the top-level block of this file or script
function exampleFunction() {
/* Function block scope */
const functionVar = "Function block variable"; // Accessible within the function block
if (true) {
const innerBlockVar = "If block variable";
console.log(functionVar); // Output: "Function block variable"
console.log(innerBlockVar); // Output: "If block variable"
}
// Cannot access innerBlockVar outside if block
// console.log(innerBlockVar); // ReferenceError: innerBlockVar is not defined
}
if (true) {
const ifBlockVar = "If block variable";
console.log(ifBlockVar); // Output: "If block variable"
}
exampleFunction();
console.log(globalVar); // Output: "Global variable"
// console.log(functionVar); // ReferenceError: functionVar is not defined
// console.log(ifBlockVar); // ReferenceError: ifBlockVar is not defined
Redeclaration and Reassignment
Redeclaration refers to declaring a variable with the same identifier (variable name) again within the same scope.
Reassignment refers to changing the value of a variable using the assignment operator (=) for the same identifier within the same scope.
| Comparison Item | var |
let |
const |
|---|---|---|---|
| Redeclaration | Allowed | Not allowed | Not allowed |
| Reassignment | Allowed | Allowed | Not allowed |
Examples
var
Variables declared with var can be redeclared and reassigned within the same scope.
You can change the value of a var variable at any time, and redeclaring a variable with the same identifier does not throw an error. The last assigned value will overwrite the previous one.
/* Initial declaration and assignment */
var myValue = 10;
console.log(myValue); // Output: 10
/* Reassignment */
myValue = 20;
console.log(myValue); // Output: 20
/* Redeclaration */
var myValue = "Hello";
console.log(myValue); // Output: "Hello" (redeclared without error)
let
Variables declared with let cannot be redeclared in the same scope.
Attempting to redeclare a let variable with the same identifier within the same scope throws an error.
// Redeclaring with let in the same scope throws an error
let exampleLet = 10;
let exampleLet = 100; // Uncaught SyntaxError: Identifier 'exampleLet' has already been declared
// However, redeclaration is allowed in a different scope:
let exampleLet = 10;
console.log(exampleLet); // Output: 10
if (true) {
let exampleLet = 100;
console.log(exampleLet); // Output: 100
}
console.log(exampleLet); // Output: 10
Reassignment is allowed within the accessible scope:
// Global scope
let globalVar = "Global variable";
console.log(globalVar); // "Global variable"
// Reassignment
globalVar = "Reassigned global variable";
console.log(globalVar); // "Reassigned global variable"
if (true) {
// Block scope
let blockVar = "Block variable";
console.log(blockVar); // "Block variable"
// Reassignment
blockVar = "Reassigned block variable";
console.log(blockVar); // "Reassigned block variable"
}
// Outside the block, not accessible
// console.log(blockVar); // ReferenceError
const
Variables declared with const cannot be redeclared in the same scope:
Redeclaring a const variable in the same scope throws an error
// Redeclaring a const variable in the same scope throws an error
const exampleConst = 10;
const exampleConst = 100; // Uncaught SyntaxError: Identifier 'exampleConst' has already been declared
// Redeclaration is allowed in a different scope:
const exampleConst = 10;
console.log(exampleConst); // Output: 10
if (true) {
const exampleConst = 100;
console.log(exampleConst); // Output: 100
}
console.log(exampleConst); // Output: 10
Reassignment of a variable declared with const cannot change the variable's value using the assignment operator (=) with the same identifier within any accessible scope, regardless of the scope where the variable was originally declared.
=) is not allowed
const exampleConst = 10;
/* Cannot change the variable's value using the assignment operator (=) with the same identifier */
exampleConst = 100; // Uncaught TypeError: Assignment to constant variable
However, if the value of the variable is a reference type such as an object or an array, you can add, update, or remove its properties or elements.
Here is an example of adding, updating, and deleting properties and values of a plain object assigned to a const variable:
// Declare a plain object
const person = {
name: 'Alice',
age: 30
};
// 1. Add a property
person.city = 'Seoul'; // Add a new property
console.log(person); // Output: { name: 'Alice', age: 30, city: 'Seoul' }
// 2. Update a property
person.age = 31; // Update an existing property
console.log(person); // Output: { name: 'Alice', age: 31, city: 'Seoul' }
// 3. Remove a property
delete person.city; // Remove a property
console.log(person); // Output: { name: 'Alice', age: 31 }
Here is an example of adding, updating, and removing elements of an array assigned to a const variable:
// Declare an array
const numbers = [1, 2, 3];
// 1. Add an element
numbers.push(4); // Add an element at the end of the array
console.log(numbers); // Output: [1, 2, 3, 4]
// 2. Update an element
numbers[0] = 10; // Update the first element
console.log(numbers); // Output: [10, 2, 3, 4]
// 3. Remove an element
numbers.pop(); // Remove the last element
console.log(numbers); // Output: [10, 2, 3]
Hoisting
Hoisting refers to the behavior in JavaScript where variable and function declarations are "moved" to the top of their scope. That is, during the code execution phase, variable or function declarations are effectively lifted to the top of their scope regardless of where they are actually written in the code.
| Comparison Item | var |
let |
const |
|---|---|---|---|
| Hoisting | Occurs (if referenced before the variable declaration, undefined is assigned) |
Occurs (if referenced before the variable declaration, an error is thrown) | Occurs (if referenced before the variable declaration, an error is thrown) |
Example
var
/*
* The variable myName declared below with var
* is hoisted as if it is positioned at the top of the scope.
* Only the declaration is hoisted; the assigned value remains in place.
*
* Since there is no value assigned at declaration,
* referencing the variable before its actual declaration
* initializes it as undefined.
*/
// Reference before the actual declaration
console.log(myName); // Output: undefined (only the declaration is hoisted, value assigned as undefined)
/* Position in code where the var variable is declared */
var myName = "John";
let, const
Variables declared with let and const are also hoisted.
However, if you reference them before their actual declaration, the JavaScript engine can detect the existence of the hoisted variable. Since let and const require strict declaration order, accessing the variable before its declaration results in an error.
TDZ (Temporal Dead Zone)
The portion of the scope from the start of the variable's scope to the actual declaration is called the Temporal Dead Zone (TDZ). TDZ applies only to variables declared with let or const.
// Start of TDZ
// ↓
console.log(myVar); // ReferenceError: Cannot access 'myVar' before initialization
// ↑
// End of TDZ
let myVar = 10;
// Start of TDZ
// ↓
console.log(myVar); // ReferenceError: Cannot access 'myVar' before initialization
// ↑
// End of TDZ
const myVar = 10;
Importance of JavaScript Variable Declarations and Scope
- Understanding proper variable declaration and scope is essential for ensuring code accuracy and stability.
- Clearly defining variable scope helps prevent naming collisions and avoids unexpected behavior.
- By controlling scope, you can manage variable visibility and lifecycle effectively.
- Proper use of variable declarations and scope improves code readability, maintainability, and reusability.
- Efficient variable management enhances developer productivity and simplifies debugging.
Therefore, understanding variable declaration methods and scope is critical in JavaScript development. Using them correctly allows you to write reliable and efficient code.
Avoid Using var for Efficient JavaScript
- By default, use
constfor variable declarations. - Use
letonly when the variable needs to be reassigned.
When working with ES6 or later, it is recommended to avoid var and use let and const for declaring variables. This approach enhances code readability and maintainability while promoting careful management of variables.
Specifications
| Specification | |
|---|---|
| Variable Statement |
ECMAScript® 2026 Language Specification #sec-variable-statement |
Compatibility
| Statement |
Desktop Chrome
|
DesktopDesktop Edge
|
Desktop Firefox
|
Safari
|
Node.js
|
|---|---|---|---|---|---|
var
|
1 | 12 | 1 | 1 | 0.10 |
let
|
49 | 14 | 44 | 10 | 6 |
const
|
21 | 12 | 36 | 5.1 | 6 |