DEV Community

Cover image for JavaScript: The differences between var, let, and const
Jenuel Oras Ganawed
Jenuel Oras Ganawed

Posted on • Originally published at jenuel.dev

JavaScript: The differences between var, let, and const

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.

function example() {
  if (true) {
    var x = 10;
  }
  console.log(x); // Outputs 10
}
example();
Enter fullscreen mode Exit fullscreen mode

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.

function example() {
  if (true) {
    let x = 10;
  }
  console.log(x); // Throws ReferenceError: x is not defined
}
example();
Enter fullscreen mode Exit fullscreen mode

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.

function example() {
  if (true) {
    let x = 10;
    console.log(x); // outputs: 10
  }
}
example();
Enter fullscreen mode Exit fullscreen mode

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.

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
Enter fullscreen mode Exit fullscreen mode

It is also good choice to use it in a conditional statement. Within ifelse 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.

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)
Enter fullscreen mode Exit fullscreen mode

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.

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
Enter fullscreen mode Exit fullscreen mode

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.

let score = 0;
score += 10; // score becomes 10
console.log(score); // Output: 10
Enter fullscreen mode Exit fullscreen mode

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.

function example() {
  const x = 10;
  x = 20; // Throws TypeError: Assignment to constant variable.
}
example();
Enter fullscreen mode Exit fullscreen mode

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.

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

const PI = 3.14159;
const MAX_SCORE = 100;
const IS_ADMIN = true;
Enter fullscreen mode Exit fullscreen mode

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.

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;
Enter fullscreen mode Exit fullscreen mode

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.

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

const area = calculateArea(5, 10);
Enter fullscreen mode Exit fullscreen mode

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

I hope you learned about varlet, 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

Top comments (2)

Collapse
 
efpage profile image
Eckehard

Object properties being always mutable is one of the major flaws of javascript. As we know: everything is an object....

So, variables defined inside classes are always mutable, as they are properties of the 'this'-object. They cannot be protected.

The only way to get some kind of "protection" are closures, that define variables inside a function scope..

Collapse
 
michaeltharrington profile image
Michael Tharrington

Excellent post in an awesome series, Jenuel! 🙌