The differences between "var" and "let" in JavaScript

In JavaScript, there are two types of variable declarations: var and let. Both keywords are used to declare variables, but they have some key differences in their behavior and scope. The var keyword has been a part of JavaScript since its inception, while let was introduced in ES6 (ECMAScript 2015).

In general, it is recommended to use let over var, as it provides more clarity and avoids some common pitfalls of JavaScript scoping. However, there may be cases where var is still a useful tool, especially when dealing with legacy code or working with certain frameworks that rely on its function-scoping behavior.

Understanding the differences between var and let is essential for writing effective and efficient JavaScript code. In this context, this article will explain the differences between var and let, how they behave, their scope, and how to use them correctly.

Scope

The main difference between var and let in JavaScript is that var is function scoped while let is block scoped.

This means that a variable declared with var can be accessed anywhere within the function where it is defined, while a variable declared with let can only be accessed within the block where it is defined (such as an if statement or a for loop).

// using var
function foo() {
  var x = 10;
  if (true) {
    var x = 20; // same variable
    console.log(x); // 20
  }
  console.log(x); // 20
}
// using let
function foo() {
  let x = 10;
  if (true) {
    let x = 20; // different variable
    console.log(x); // 20
  }
  console.log(x); // 10
}

Redeclaration

Another difference is that var allows you to redeclare the same variable in the same scope, while let does not.

// using var
var x = 10;
var x = 20; // no error
console.log(x); // 20
// using let
let x = 10;
let x = 20; // error: Identifier 'x' has already been declared
console.log(x);

Hoisting

A third difference is that var variables are hoisted to the top of their scope, while let variables are not. This means that you can use a var variable before it is declared, but not a let variable.

// using var
console.log(x); // undefined (no error)
var x = 10;
// using let
console.log(x); // error: x is not defined
let x = 10;

Initialization

When you declare a variable with var, it is initialized with a value of undefined. This means that you can use a var variable before it is assigned a value, but it will have the value of undefined.

// using var
console.log(x); // undefined (no error)
var x = 10;

When you declare a variable with let, it is not initialized. This also means that let variables have a “temporal dead zone” (TDZ), which is the time between the variable declaration and its initialization. During this time, the variable cannot be accessed or referenced.

// using let
let x = 10; // declaration and initialization
console.log(x); // 10 (no error)
{ // TDZ starts here
  console.log(x); // error: x is not defined
  let x = 20; // TDZ ends here
  console.log(x); // 20 (no error)
}

In the above example, the second block creates a new scope for x, and declares and initializes it with a value of 20. However, before that line is reached, x is not initialized and cannot be used. Hence, the first console.log inside the block throws an error. If you remove the declaration and initialization of x inside the block then everything will be fine.