When writing JavaScript, managing data is fundamental, and variables are how we store that data. Understanding the different ways to declare variables is crucial for writing clean, predictable, and maintainable code in modern JavaScript development.
var: The legacy, and why we rarely use it for new code (hoisting, function scope pitfalls).
var
is the oldest way to declare variables in JavaScript. While still functional, its hoisting behavior and function-level scoping can lead to unexpected bugs, making let
and const
preferred for new development.
Example 1: var
Hoisting
console.log(myVar); // Output: undefined (hoisted, but not initialized)
var myVar = "Hello World";
console.log(myVar); // Output: Hello World
Explanation This code demonstrates var
hoisting. The declaration var myVar
is moved to the top of its scope, so myVar
exists, but its assignment happens later, resulting in undefined
initially.
Example 2: var
Function Scope
function greet() {
var message = "Hi there!";
if (true) {
var message = "Hello again!"; // This re-declares the same variable
console.log(message); // Output: Hello again!
}
console.log(message); // Output: Hello again!
}
greet();
Explanation This example shows var
's function scope. The message
variable is scoped to the entire greet
function, meaning the if
block's declaration overwrites the initial one.
Example 3: Accidental Global var
function setName() {
firstName = "John"; // Without 'var', 'let', or 'const', this becomes a global variable
}
setName();
console.log(firstName); // Output: John (accessible globally)
Explanation This illustrates how omitting var
, let
, or const
can accidentally create global variables, polluting the global namespace and potentially causing conflicts.
Example 4: var
in Loops (Common Pitfall)
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i); // Output: 3, 3, 3 (not 0, 1, 2)
}, 100);
}
Explanation Here, var i
is function-scoped. By the time setTimeout
executes, the loop has finished, and i
is 3 for all iterations, a common pitfall.
Example 5: Redeclaring var
var fruit = "apple";
var fruit = "banana"; // Valid, 'var' allows redeclaration
console.log(fruit); // Output: banana
Explanation This shows that var
allows redeclaring the same variable within the same scope without an error, which can lead to unexpected overwrites.
let: The new workhorse. Block-scoped, reassignable.
let
is the modern standard for declaring variables that may be reassigned. It introduces block-scoping, which limits the variable's visibility to the block ({}
) where it's defined, providing more predictable behavior than var
.
Example 1: let
Block Scope
let count = 10;
if (true) {
let count = 20; // This is a new, separate 'count' variable
console.log(count); // Output: 20
}
console.log(count); // Output: 10
Explanation This demonstrates let
's block scope. The count
inside the if
block is a distinct variable, preventing accidental modification of the outer count
.
Example 2: Reassigning let
let userName = "Alice";
console.log(userName); // Output: Alice
userName = "Bob"; // 'let' allows reassignment
console.log(userName); // Output: Bob
Explanation This example clearly shows that a variable declared with let
can have its value reassigned after its initial declaration.
Example 3: let
in Loops (Correct Behavior)
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i); // Output: 0, 1, 2 (as expected)
}, 100);
}
Explanation With let
, each iteration of the loop creates a new i
variable within that iteration's scope, correctly capturing the value for each setTimeout
.
Example 4: let
and Redeclaration Error
let city = "London";
// let city = "Paris"; // This would throw a 'SyntaxError: Identifier 'city' has already been declared'
console.log(city);
Explanation Unlike var
, let
prevents redeclaring the same variable within the same scope, helping to catch potential naming conflicts early.
Example 5: let
and Temporal Dead Zone
// console.log(tempVar); // This would throw a ReferenceError (Temporal Dead Zone)
let tempVar = "Hello";
console.log(tempVar); // Output: Hello
Explanation Variables declared with let
(and const
) exist in a "temporal dead zone" from the start of their block until their declaration is processed, preventing access before initialization.
const: For values that won't change. Block-scoped, prevents reassignment. Immutability concepts.
const
is used for variables whose values are intended to remain constant throughout the program's execution. It is also block-scoped and prevents reassignment after the initial declaration, promoting immutability for primitives.
Example 1: const
Immutability (Primitives)
const PI = 3.14159;
// PI = 3.14; // This would throw a TypeError: Assignment to constant variable.
console.log(PI); // Output: 3.14159
Explanation This demonstrates that primitive values declared with const
cannot be reassigned, ensuring their value remains constant.
Example 2: const
with Objects (Mutability)
const person = {
name: "Jane",
age: 30
};
console.log(person.name); // Output: Jane
person.age = 31; // Allowed: properties of the object can be changed
console.log(person.age); // Output: 31
// person = { name: "John" }; // This would throw a TypeError: Assignment to constant variable.
Explanation While const
prevents reassignment of the person
object itself, it does not prevent modification of the object's properties. This is a key concept of immutability in JavaScript.
Example 3: const
and Block Scope
const maxItems = 5;
if (true) {
const maxItems = 10; // This is a new, separate 'maxItems'
console.log(maxItems); // Output: 10
}
console.log(maxItems); // Output: 5
Explanation Similar to let
, const
variables are block-scoped. The maxItems
inside the if
block is distinct from the outer one.
Example 4: const
and Initialization
// const APP_NAME; // This would throw a SyntaxError: Missing initializer in const declaration
const APP_NAME = "My Application"; // Must be initialized
console.log(APP_NAME); // Output: My Application
Explanation const
variables must be initialized at the time of their declaration, as they cannot be reassigned later.
Example 5: const
with Arrays (Mutability)
const colors = ["red", "green"];
colors.push("blue"); // Allowed: array elements can be modified
console.log(colors); // Output: ["red", "green", "blue"]
// colors = ["yellow"]; // This would throw a TypeError: Assignment to constant variable.
Explanation Like objects, arrays declared with const
cannot be reassigned, but their contents (elements) can be modified using array methods like push
or pop
.