Na navigaci | Klávesové zkratky

Var, Let, Const: Stop Complicating Your Life in JavaScript

JavaScript offers three ways to declare variables: var, let, and const. Many programmers aren't entirely clear on when to use which one, and most tutorials and linters force you to use them incorrectly. Let's see how to write cleaner and more understandable code without unnecessary rules that don't actually help us.

Let's Start with the Most Dangerous Part

JavaScript has one treacherous quirk: by simply omitting a variable declaration, you can unknowingly use a global variable. All it takes is forgetting var, let, or const:

function calculatePrice(amount) {
    price = amount * 100;    // Omission! Missing 'let'
    return price;            // We're using a global variable 'price'
}

function processOrder() {
    price = 0;               // We're using the same global variable!
    // ... some code calling calculatePrice()
    return price;            // We're returning a completely different value than expected
}

This is every developer's nightmare – the code appears to work correctly until something mysteriously starts failing elsewhere in the application. Debugging such errors can take hours because a global variable can be overwritten anywhere in the application.

That's why it's absolutely crucial to always declare variables using let or const.

Forget About var

The var keyword has been in JavaScript since its inception in 1995 and carries some problematic properties that were considered features at the time of the language's creation but proved to be a source of many bugs over time. After twenty years of language development, JavaScript's authors decided to address these problems – not by fixing var (to maintain backward compatibility) but by introducing the new let keyword in ES2015.

You can find plenty of articles on the internet dissecting the problems with var in the finest detail. But you know what? There's no need to get bogged down in the details. Let's just treat var as a relic of the past and focus on modern JavaScript.

When to Use let

let is the modern way to declare variables in JavaScript.

The nice thing is that the variable only exists within the code block (between curly braces) where it was defined. This makes the code more predictable and safer.

if (someCondition) {
    let temp = calculateSomething();
    // temp is only available here
}
// temp no longer exists here

In loops, the declaration is technically placed before the curly braces, but don't let that confuse you – the variable only exists within the loop:

for (let counter = 0; counter < 10; counter++) {
    // The counter variable only exists in the loop
}
// counter is no longer accessible here

When to Use const

const is used to declare constants. These are typically important values at the module or application level that should never change:

const PI = 3.14159;
const API_URL = 'https://api.example.com';
const MAX_RETRY_ATTEMPTS = 3;

However, it's important to understand one key detail: const only prevents assigning a new value to the variable – it doesn't control what happens with the value itself. This distinction is particularly evident with objects and arrays (an array is also an object) – const doesn't make them immutable objects, i.e., it doesn't prevent changes inside the object:

const CONFIG = {
    url: 'https://api.example.com',
    timeout: 5000
};

CONFIG.url = 'https://api2.example.com';  // This works!
CONFIG = { url: 'https://api2.example.com' };  // This throws TypeError!

If you need a truly immutable object, you need to freeze it first.

The let vs const Dilemma

Now we come to a more interesting question. While the situation with var vs let is clear, the use of const is the subject of many community discussions. Most tutorials, style guides, and linters promote the rule “use const wherever you can.” So we commonly see const used in function or method bodies.

Let's explain why this popular “best practice” is actually an anti-pattern that makes code less readable and unnecessarily restrictive.

The approach “if a variable's value isn't reassigned in the code, it should be declared as const” seems logical at first glance. Why else would const even exist? The more “constants,” the safer and more predictable the code, right? And faster too, because the compiler can better optimize it.

However, this entire approach fundamentally misunderstands the purpose of constants. It's primarily about communicating intent – are we truly trying to signal to other developers that this variable should never be reassigned, or do we just happen not to reassign it in our current implementation?

// Real constants - values that are constant by their nature
const PI = 3.14159;
const DAYS_IN_WEEK = 7;
const API_ENDPOINT = 'https://api.example.com';

// vs.

function processOrder(items) {
    // These AREN'T constants, we just happen to not reassign them
    const total = items.reduce((sum, item) => sum + item.price, 0);
    const tax = total * 0.21;
    const shipping = calculateShipping(total);
    return { total, tax, shipping };
}

In the first case, we have values that are constants by their nature – they express immutable properties of our system or important configuration data. When we see PI or API_ENDPOINT somewhere in the code, we immediately understand why these values are constants.

In the second case, we're using const just because we happen to not reassign the values right now. But that's not their essential characteristic – these are regular variables that we might want to change in the next version of the function. And when we want to do that, const will unnecessarily prevent us.

In the days when JavaScript was one big global code, it made sense to try to secure variables against reassignment. But today we write code in modules and classes. Today it's common and correct that the scope is a small function, and within its scope, it makes no sense to worry about the difference between let and const.

Because it creates completely unnecessary mental overhead:

  1. The programmer has to think while writing: “Will I change this value? No? Then I must use const…”
  2. It distracts readers! When they see const in the code, they wonder: “Why is this a constant? Is this some important value? Does it have any significance?”
  3. In a month we need to change the value and have to deal with: “Can I change const to let? Is someone relying on this?”

Simply use let and you don't have to deal with these questions at all.

It's even worse when this decision is made automatically by a linter. That is, when the linter “fixes” variables to const because it only sees one assignment. The code reader then unnecessarily wonders: “Why must these variables be constants here? Is it somehow important?” And yet it's not important – it's just a coincidence. Don't use the prefer-const rule in ESLint!

By the way, the optimization argument is a myth. Modern JavaScript engines (like V8) can easily detect whether a variable is reassigned or not, regardless of whether it was declared using let or const. So using const provides no performance benefit.

Implicit Constants

In JavaScript, there are several constructs that implicitly create constants without us having to use the const keyword:

// imported modules
import { React } from 'react';
React = something; // TypeError: Assignment to constant variable

// functions
function add(a, b) { return a + b; }
add = something; // TypeError: Assignment to constant variable

// classes
class User {}
User = something; // TypeError: Assignment to constant variable

This makes sense – these constructs define the basic building blocks of our code, and overwriting them could cause chaos in the application. That's why JavaScript automatically protects them against reassignment, just as if they were declared using const.

Constants in Classes

Classes were added to JavaScript relatively recently (in ES2015), and their functionality is still gradually maturing. For example, private members marked with # didn't arrive until 2022. JavaScript is still waiting for class constant support. For now, you can use static, but it's far from the same thing – it marks a value shared between all class instances, not an immutable one.

Conclusion

  1. Don't use var – it's outdated
  2. Use const for real constants at the module level
  3. In functions and methods, use let – it's more readable and clearer
  4. Don't let the linter automatically change let to const – it's not about the number of assignments, but about intent

You might be interested in

Leave a comment

Text of the comment
Contact

(kvůli gravataru)



*kurzíva* **tučné** "odkaz":http://example.com /--php phpkod(); \--

phpFashion © 2004, 2025 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.