JavaScript > ES6 and Beyond > New Syntax and Features > let and const
Understanding `let` and `const` in JavaScript
This snippet explores the `let` and `const` keywords introduced in ES6, providing a comparison with `var` and demonstrating their usage and scope differences.
Basic Declaration and Assignment
The `let` keyword declares a block-scoped variable that can be reassigned. The `const` keyword declares a block-scoped constant that cannot be reassigned after its initial declaration. Attempting to reassign a `const` variable will result in a TypeError.
// Using let
let myVariable = 10;
console.log(myVariable); // Output: 10
myVariable = 20;
console.log(myVariable); // Output: 20
// Using const
const myConstant = 30;
console.log(myConstant); // Output: 30
// myConstant = 40; // This will throw an error: Assignment to constant variable.
Block Scope vs. Function Scope
`var` is function-scoped, meaning it's accessible throughout the function in which it's declared, even if it's declared inside a block (like an `if` statement). `let` and `const` are block-scoped, meaning they are only accessible within the block in which they are defined (e.g., within an `if` statement, a `for` loop, or a code block surrounded by curly braces `{}`).
// var (function-scoped)
function myFunction() {
if (true) {
var x = 10;
}
console.log(x); // Output: 10 - Accessible because var is function-scoped
}
myFunction();
// let (block-scoped)
function myOtherFunction() {
if (true) {
let y = 20;
const z = 30;
}
// console.log(y); // This will throw an error: y is not defined
// console.log(z); // This will throw an error: z is not defined
}
myOtherFunction();
Hoisting
Hoisting is JavaScript's behavior of moving declarations to the top of their scope before code execution. `var` variables are hoisted and initialized to `undefined`. `let` and `const` variables are also hoisted, but they are not initialized. This means that attempting to access them before their declaration results in a `ReferenceError` (the "temporal dead zone").
//Hoisting behavior with var, let and const
console.log(a); // Output: undefined - var is hoisted and initialized to undefined
// console.log(b); // This will throw an error: Cannot access 'b' before initialization - let is hoisted but not initialized
// console.log(c); // This will throw an error: Cannot access 'c' before initialization - const is hoisted but not initialized
var a = 10;
let b = 20;
const c = 30;
Real-Life Use Case: Loop Counters
When using `var` in loops with asynchronous operations (like `setTimeout`), the variable `i` is not scoped to each iteration. By the time the `setTimeout` callbacks execute, the loop has already completed, and `i`'s value is 5. `let` solves this issue by creating a new binding for `j` in each iteration of the loop, so each `setTimeout` callback closes over the correct value.
// Using var (problematic in loops)
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log('var loop: ' + i);
}, 100);
}
// Output: var loop: 5
// var loop: 5
// var loop: 5
// var loop: 5
// var loop: 5
// Using let (correct behavior)
for (let j = 0; j < 5; j++) {
setTimeout(function() {
console.log('let loop: ' + j);
}, 100);
}
// Output: let loop: 0
// let loop: 1
// let loop: 2
// let loop: 3
// let loop: 4
Best Practices
Interview Tip
Be prepared to explain the differences between `var`, `let`, and `const`, focusing on scope, hoisting, and mutability. Understand the implications of using `var` in loops and how `let` solves the common closure problem. Be ready to discuss the concept of the temporal dead zone.
When to Use Them
Memory footprint
The memory footprint of `let` and `const` is generally the same as `var`. The key difference is how the JavaScript engine manages the scope and mutability of these variables, not necessarily the amount of memory they consume directly. Using `const` can potentially allow the engine to perform some optimizations, knowing that the value won't change, but this is highly implementation-dependent.
Alternatives
There aren't really direct alternatives to `let` and `const` in modern JavaScript. `var` is the predecessor, but it has well-known drawbacks regarding scope. In some functional programming paradigms, you might favor immutability more heavily, reducing the need for `let` by designing functions to return new values instead of modifying existing ones.
Pros
Cons
FAQ
-
What happens if I try to reassign a `const` variable?
You'll get a `TypeError: Assignment to constant variable.` error. `const` variables are meant to be immutable after their initial assignment. -
Are `const` objects truly immutable?
No. `const` means that the *reference* to the object cannot be changed. However, the properties of the object itself can still be modified. If you want true immutability, you can use `Object.freeze()`. -
Can I declare a `const` variable without initializing it?
No. `const` variables must be initialized when they are declared. Otherwise, you'll get a `SyntaxError: Missing initializer in const declaration`.