🟨 JavaScript Q104 / 104

What is the difference between let, const and var?

AI-Powered Answer ✓ Answered

In JavaScript, `var`, `let`, and `const` are keywords used for declaring variables. While they all serve this fundamental purpose, they differ significantly in terms of scope, hoisting, and mutability, impacting how variables behave in your code. Understanding these differences is crucial for writing robust and predictable JavaScript applications.

`var` Keyword

The var keyword was the original way to declare variables in JavaScript prior to ES6 (ECMAScript 2015). Variables declared with var are function-scoped or globally-scoped, meaning they are accessible throughout the entire function in which they are declared, or globally if declared outside any function.

var variables are hoisted to the top of their scope and initialized with undefined. They can be re-declared and re-assigned within the same scope without error, which can sometimes lead to unexpected behavior and bugs, especially in larger codebases.

javascript
function exampleVar() {
  console.log(myVar); // undefined (hoisted, but not yet assigned)
  var myVar = 10;
  console.log(myVar); // 10

  if (true) {
    var myVar = 20; // Re-declared and re-assigned within the same function scope
    console.log(myVar); // 20
  }
  console.log(myVar); // 20 (still accessible and modified across the function)
}
exampleVar();

var globalVar = 5;
var globalVar = 15; // Allowed re-declaration in global scope
console.log(globalVar); // 15

`let` Keyword

Introduced in ES6, let allows you to declare block-scoped variables. This means a variable declared with let is only accessible within the block (curly braces {}) where it is defined, as well as any nested blocks. This provides more control over variable visibility compared to var.

Like var, let variables are hoisted, but they are not initialized. Instead, they enter a 'temporal dead zone' from the start of the block until their declaration is processed. Accessing a let variable before its declaration results in a ReferenceError. let variables can be re-assigned but cannot be re-declared within the same scope, preventing common mistakes seen with var.

javascript
function exampleLet() {
  // console.log(myLet); // ReferenceError: Cannot access 'myLet' before initialization (Temporal Dead Zone)
  let myLet = 10;
  console.log(myLet); // 10

  if (true) {
    let myLet = 20; // This is a new, separate variable, block-scoped to the if block
    console.log(myLet); // 20
  }
  console.log(myLet); // 10 (the outer myLet is untouched)

  myLet = 30; // Re-assignment is allowed for the outer myLet
  console.log(myLet); // 30

  // let myLet = 40; // SyntaxError: Identifier 'myLet' has already been declared (in this scope)
}
exampleLet();

`const` Keyword

const, also introduced in ES6, is used to declare block-scoped constants. Similar to let, const variables are block-scoped and exist within a temporal dead zone until their declaration. The main characteristic of const is that it creates a read-only reference to a value.

A const variable must be initialized at the time of declaration and cannot be re-assigned. For primitive values (numbers, strings, booleans), this means the value itself cannot change. For objects and arrays, the reference to the object/array cannot change, but the properties or elements of the object/array can still be modified, as the reference itself remains constant.

javascript
function exampleConst() {
  // const myConst; // SyntaxError: Missing initializer in const declaration
  const myConst = 10;
  console.log(myConst); // 10

  // myConst = 20; // TypeError: Assignment to constant variable.

  if (true) {
    const myConst = 30; // New block-scoped variable
    console.log(myConst); // 30
  }
  console.log(myConst); // 10 (the outer myConst is untouched)

  const myObject = { name: 'Alice', age: 30 };
  myObject.name = 'Bob'; // Allowed: property of the object can be modified
  myObject.age = 31;
  console.log(myObject); // { name: 'Bob', age: 31 }

  // myObject = { name: 'Charlie' }; // TypeError: Assignment to constant variable. (reference cannot change)
}
exampleConst();

Summary of Differences

Feature`var``let``const`
ScopeFunction-scoped or Global-scopedBlock-scopedBlock-scoped
HoistingYes, initialized with `undefined`Yes, but in Temporal Dead ZoneYes, but in Temporal Dead Zone
Re-declarationAllowedNot AllowedNot Allowed
Re-assignmentAllowedAllowedNot Allowed (for the reference)
InitializationOptionalOptionalRequired at declaration

Best Practices

In modern JavaScript, it is generally recommended to avoid var entirely due to its confusing scope and hoisting behavior. Use const by default for any variable that does not need to be re-assigned. If you anticipate that a variable's value will need to change, then use let. This approach enhances code readability, predictability, and helps prevent common programming errors by ensuring variables have the narrowest possible scope and mutability as intended.