JavaScript let and const

Before the release of ES6 (ECMAScript 2015), JavaScript developers were limited to using var for variable declarations. This often led to confusing bugs due to "hoisting" and lack of block-level scoping. The introduction of let and const changed the game, giving us more control over how data lives and changes within our applications.

let Declaration

Scope:

  • let allows block-scoped variable declarations. A "block" is generally any code wrapped inside curly braces { }, such as if statements, for loops, or functions.
  • Variables declared with let are trapped within the block where they are defined. They cannot be accessed from the outside, which prevents variable leakage and accidental overwrites.
Developer Tip: Use let whenever you know a variable's value will need to change over time, such as a counter in a loop or a toggle for a UI element.

Reassignment:

  • Variables declared with let can be reassigned a new value as your program runs. However, unlike var, you cannot re-declare the same variable name within the same scope.
Common Mistake: Trying to re-declare a let variable in the same scope will throw a SyntaxError.
let name = "Alice";
let name = "Bob"; // Error: Identifier 'name' has already been declared

Example: Block Scope

In this example, notice how the x inside the if block is completely independent of the x outside of it.

let x = 10;
if (true) {
  let x = 20; // This is a different 'x' than the one above
  console.log(x); // Output: 20
}
console.log(x); // Output: 10 (the outer scope remains unchanged)

Example: Loop Iteration

One of the biggest advantages of let is how it behaves in loops. Each iteration of the loop gets its own unique "binding" of the variable.

for (let i = 0; i < 5; i++) {
  setTimeout(() => {
    // Because of block scope, 'i' is captured correctly for each timer
    console.log(i); // Outputs 0, 1, 2, 3, 4
  }, 1000);
}
Best Practice: Always prefer let or const over var. This makes your code more predictable and easier to debug because variables don't "leak" out of the blocks where they are intended to stay.

 

const Declaration

Immutability:

  • const (short for constant) is used for variables that should not be reassigned. Once you assign a value to a const, you cannot give it a new value later.
  • This provides a strong hint to other developers that this specific piece of data is meant to stay the same throughout the lifecycle of the script.

Scope:

  • Just like let, const is block-scoped. It respects the boundaries of the { } it was created in.

Initialization:

  • You must assign a value to a const variable the moment you declare it. You cannot leave it undefined and assign it later.
Watch Out: const does not make the value immutable if that value is an object or an array. It only prevents the variable name from being pointed to a new data structure.

Example: Immutable Value

const PI = 3.14;
// PI = 3.14159; // Error: Assignment to constant variable

Example: Object Constants

While you cannot reassign the variable person to a different object, you are free to change the properties inside that object.

const person = {
  name: 'John',
  age: 30
};

// This is perfectly fine:
person.age = 31; 

// This will cause an error:
// person = { name: 'Jane' }; 

Example: Array Constants

Similarly, you can add or remove items from a const array, but you cannot replace the array itself with a new one.

const colors = ['red', 'green', 'blue'];

// This is allowed:
colors.push('yellow'); 

// This will cause an error:
// colors = ['black', 'white']; 

 

Key Points

  • Default to const: Modern JavaScript best practices suggest using const for everything by default. Only switch to let if you realize the value actually needs to be reassigned.
  • let variables have block scope and can be reassigned, making them perfect for loop counters or mathematical calculations.
  • const variables prevent reassignment, which helps avoid bugs where you accidentally overwrite a variable that should stay constant (like a configuration setting or a library import).
  • Temporal Dead Zone: Both let and const cannot be used before they are declared in your code. If you try to access them earlier, JavaScript will throw a ReferenceError.
Developer Tip: If you want to make an object truly immutable so that even its properties cannot be changed, look into using Object.freeze(myObject).