JavaScript: The differences between var, let, and const
Tags: javascript, webdev, programming, beginners
Published: 2024-05-10 13:37:23

JavaScript, the backbone of modern web development, offers developers a myriad of tools to manipulate data and control the flow of their applications. Among these tools are three keywords for declaring variables: var, let, and const. While they may seem interchangeable at first glance, understanding their nuances is crucial for writing efficient and maintainable code. In this blog post, we'll delve into the differences between var, let, and const in JavaScript.

## `var`: The Legacy Keyword

Historically, var was the only way to declare variables in JavaScript. It has function scope, meaning variables declared with var are scoped to the function in which they are declared, rather than the block in which they are defined. This can lead to unexpected behavior, especially in loops or nested functions.

```js
function example() {
  if (true) {
    var x = 10;
  }
  console.log(x); // Outputs 10
}
example();
```

In this example, even though x is declared within the if block, it's accessible outside of it due to var's function scope.

These days, `var` is not recommended, and here are some of the reasons why you should be using `let` and `const` :

- `var` has function scope, meaning variables declared with `var` are accessible throughout the entire function, even within nested blocks (like `if` statements or loops) within the function.
    
- With `var`, variables are hoisted to the top of their function scope. This means you can access a variable declared with `var` even before its actual declaration in the code. This can be confusing for beginners and can lead to bugs if you're not aware of hoisting.
    
- You can **redeclare** a variable with `var` within the same scope, potentially overwriting the original value unintentionally.
    
- `var` variables technically exist in their scope from the beginning, but they cannot be accessed until their declaration is reached. This creates a **TDZ** where the variable is inaccessible.
    

## `let`: Block Scope for Modern Development

Introduced in `ECMAScript 6 (ES6)` in June 2015. `let` provides block scope, meaning variables declared with `let` are scoped to the block in which they are defined. This makes let a safer and more predictable option compared to var.

```js
function example() {
  if (true) {
    let x = 10;
  }
  console.log(x); // Throws ReferenceError: x is not defined
}
example();
```

Unlike var, attempting to access x outside of the if block results in a `ReferenceError`, highlighting let's block-level scope. So, the best option would be putting it inside a block, like so.

```js
function example() {
  if (true) {
    let x = 10;
    console.log(x); // outputs: 10
  }
}
example();
```

The `let` keyword is a fundamental concept in JavaScript for declaring variables with **block-level scope**. This means that variables declared with `let` are only accessible within the block (typically enclosed in curly braces `{}`) where they are defined. This provides a clear and predictable way to manage variable scope, preventing unintended side effects and making your code more maintainable.

Let is a preferred choice when working with Loops. In loops (like `for` or `while`), you often need a variable to keep track of the current iteration. `let` ensures that this counter variable is only accessible within the loop's block, preventing conflicts with other variables in your code.

```js
for (let i = 0; i < 5; i++) {
    console.log(i); // Output: 0, 1, 2, 3, 4
}

// Here, 'i' is no longer accessible
console.log(i); // ReferenceError: i is not defined
```

It is also good choice to use it in a conditional statement. Within `if`, `else if`, or `switch` statements, you might need temporary variables to store values based on certain conditions. `let` creates variables that are local to the conditional block, avoiding conflicts with variables outside.

```js
let message;
if (age >= 18) {
    message = "You are eligible to vote.";
} else {
    message = "You are not eligible to vote yet.";
}

console.log(message); // Output: "You are eligible to vote." (assuming age >= 18)
```

While `let` primarily focuses on block scope, it also introduces a more predictable behavior within functions compared to the older `var` keyword. Variables declared with `let` inside a function are not accessible outside that function, promoting better organization and preventing accidental modifications.

```js
function greet(name) {
    let greeting = "Hello, " + name;
    console.log(greeting); // Output: "Hello, Alice" (assuming name is "Alice")
}

greet("Alice");

// 'greeting' is not accessible here
console.log(greeting); // ReferenceError: greeting is not defined
```

If you intend to change the value of a variable within its scope, let is the appropriate choice. It allows you to update the variable's content as needed.

```js
let score = 0;
score += 10; // score becomes 10
console.log(score); // Output: 10
```

## `const`: Immutable Variables

Similar to let, const was also introduced in ES6 and provides block scope. However, variables declared with const are immutable, meaning their value cannot be reassigned once initialized. This makes const ideal for declaring constants or variables that shouldn't be modified.

```js
function example() {
  const x = 10;
  x = 20; // Throws TypeError: Assignment to constant variable.
}
example();
```

Attempting to reassign a value to a constant variable result in a `TypeError`, enforcing immutability.

The primary purpose of `const` is to declare variables whose values you intend to remain constant throughout the code's execution. This makes your code more readable, predictable, and less prone to errors by preventing accidental reassignments.

`Numbers`, `strings`, and `booleans` that represent fixed values are ideal candidates for const. For example:

```js
const PI = 3.14159;
const MAX_SCORE = 100;
const IS_ADMIN = true;
```

When you create objects or arrays and want their properties or elements to remain fixed, use `const`. However, keep in mind that while the reference to the object or array itself is constant, you can still **modify** the contents within them using methods like push, pop, and object property assignment.

```js
const person = {
    name: "Alice",
    age: 30
};

// This will throw an error because you're trying to reassign the reference to 'person'
person = { name: "Bob" };

// This is allowed because your modifying the property name  within the existing object
perons.name = "Bob";

// This is allowed because you're modifying the property within the existing object
person.age = 31;
```

How about function arguments? If you don't plan to modify the value of a function argument, declare it with `const`. This enhances code readability and prevents unintended changes.

```js
function calculateArea(const width, const height) {
    return width * height;
}

const area = calculateArea(5, 10);
```

While `const` **prevents** reassignment of the variable itself, it doesn't guarantee immutability of complex data types like **objects and arrays**. You can still modify their contents using methods. For true immutability, consider libraries like `immer`.

Use `const` by default for variables that **don't need reassignment** improves code clarity and makes your intent explicit. It also promotes a more consistent coding style.

When a variable's value won't change, const makes the code easier to understand and helps prevent bugs caused by accidental modifications.

![image about const var let](https://i.imgur.com/SRQnXFy.jpg)

I hope you learned about `var`, `let`, and `const`, Cheers 🍻

---

If you enjoy this article and would like to show your support, you can easily do so by buying me a coffee. Your contribution is greatly appreciated!

[![Jenuel Ganawed Buy me Coffee](https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee&emoji=%E2%98%95&slug=jenuel.dev&button_colour=FFDD00&font_colour=000000&font_family=Inter&outline_colour=000000&coffee_colour=ffffff)](https://www.buymeacoffee.com/jenuel.dev)