5 Variable Declarations
In JavaScript, the keywords let
, const
, and var
are all used to declare variables, but they have important differences in terms of scope, hoisting, reassignment capabilities, and when they were introduced to the language. Let me walk you through each one and explain when to use them.
5.1 When to Use Each Declaration
Here’s a practical guide for when to use each type of declaration:
5.1.1 Use const
by default:
- It makes your intentions clear - this value shouldn’t change
- Helps prevent bugs from accidental reassignment
- Use for all variables that won’t be reassigned
5.1.2 Use let
when you need to reassign:
- Loop counters (
for (let i = 0; i < 10; i++)
) - Variables that change value throughout your code
- When you’re accumulating a value
5.1.3 Avoid var
in modern code:
- It’s considered outdated in modern JavaScript
- The lack of block scoping can lead to unexpected bugs
- Less predictable behavior due to hoisting
5.2 var
: The Original Variable Declaration
var
was the original way to declare variables in JavaScript before ES6 (ECMAScript 2015).
var name = "John";
var age = 30;
5.2.1 Key Characteristics of var
:
- Function-scoped: Variables declared with
var
are scoped to the function in which they are declared, or globally if declared outside any function.
function exampleFunction() {
var insideVar = "I'm inside the function";
console.log(insideVar); // Works fine
}// console.log(insideVar); // Would throw ReferenceError
- Hoisting: Variables declared with
var
are “hoisted” to the top of their scope, which means you can use them before their declaration in the code.
console.log(hoistedVar); // Outputs: undefined (not an error!)
var hoistedVar = "I'm hoisted";
What actually happens behind the scenes is:
var hoistedVar; // Declaration is hoisted
console.log(hoistedVar); // undefined
= "I'm hoisted"; // Assignment stays in place hoistedVar
- No block scope:
var
doesn’t respect block scope (like inif
statements or loops):
if (true) {
var blockVar = "I'm in a block";
}console.log(blockVar); // Outputs: "I'm in a block" (leaks outside the block!)
- Can be redeclared: You can declare the same variable multiple times without errors:
var example = "first";
var example = "second"; // No error, just overwrites
5.3 let
: Block-Scoped Variable Declaration
let
was introduced in ES6 (2015) to address issues with var
.
let name = "John";
let age = 30;
5.3.1 Key Characteristics of let
:
- Block-scoped: Variables declared with
let
are scoped to the nearest curly braces{}
(block).
if (true) {
let blockLet = "I'm in a block";
console.log(blockLet); // Works fine
}// console.log(blockLet); // ReferenceError: blockLet is not defined
- Hoisting with temporal dead zone:
let
variables are hoisted but not initialized, creating what’s called a “temporal dead zone” where accessing the variable before declaration throws an error.
// console.log(hoistedLet); // ReferenceError: Cannot access 'hoistedLet' before initialization
let hoistedLet = "I'm hoisted differently";
- Cannot be redeclared: You cannot declare the same variable multiple times in the same scope:
let example = "first";
// let example = "second"; // SyntaxError: Identifier 'example' has already been declared
- Can be reassigned: You can change the value after declaration:
let count = 1;
= 2; // This is allowed count
5.4 const
: Constant Variable Declaration
const
was also introduced in ES6 alongside let
.
const PI = 3.14159;
const MAX_USERS = 100;
5.4.1 Key Characteristics of const
:
- Block-scoped: Just like
let
,const
variables are block-scoped.
if (true) {
const blockConst = "I'm in a block";
console.log(blockConst); // Works fine
}// console.log(blockConst); // ReferenceError: blockConst is not defined
Hoisting with temporal dead zone: Similar to
let
,const
variables are hoisted but not initialized until their declaration is reached.Cannot be redeclared: Like
let
, you cannot redeclare aconst
variable in the same scope.Cannot be reassigned: This is the key difference between
const
andlet
- once assigned, aconst
variable cannot be given a new value:
const PI = 3.14;
// PI = 3.14159; // TypeError: Assignment to constant variable
However, for objects and arrays (which are reference types), the contents can still be modified:
const person = { name: "John" };
.name = "Jane"; // This works! The object's content can change
person// person = { name: "Jane" }; // This would fail - cannot reassign the reference
const numbers = [1, 2, 3];
.push(4); // This works! The array's content can change
numbers// numbers = [1, 2, 3, 4]; // This would fail - cannot reassign the reference
5.5 Practical Example Putting It All Together
Here’s a practical example showing all three in action:
function calculateTotalPrice(items, taxRate) {
// Using const for values that won't change
const TAX_MULTIPLIER = 1 + taxRate;
// Using let for a counter that will be updated
let subtotal = 0;
// In older code, you might see var
var discountApplied = false;
// A loop using let for the counter
for (let i = 0; i < items.length; i++) {
const item = items[i]; // Each iteration gets a new constant
+= item.price;
subtotal
if (item.discounted) {
= true;
discountApplied
}
}
// Block scope demonstration
if (discountApplied) {
const message = "Discount applied!";
console.log(message); // Works
// let scoped message
let detail = "Some items were on sale";
console.log(detail); // Works
}// console.log(message); // Would throw ReferenceError - const is block-scoped
// console.log(detail); // Would throw ReferenceError - let is block-scoped
console.log(discountApplied); // Works - var is function-scoped
// Calculate and return the final price
const totalPrice = subtotal * TAX_MULTIPLIER;
return totalPrice;
}
5.6 How This Relates to Your Experience
Since you’re coming from R and Python:
const
is similar to constants in other languages or final variableslet
is closest to most variable declarations in Python- R doesn’t have block scope the same way JavaScript does, so this might be a new concept
- Python’s scoping rules are cleaner than
var
but not quite as strict aslet
/const
Modern JavaScript best practices strongly favor const
and let
over var
. As a beginner focused on learning modern JavaScript, you’ll want to make the same habit.
Does this explanation help clarify the differences? Is there any specific aspect of variable declarations you’d like me to go into more detail on?