Skip to content Skip to footer

JavaScript’s const vs var: The Eternal Debate

JavaScript’s evolution has been nothing short of a rollercoaster ride, and with ES6 (ECMAScript 2015), we got a fresh take on variable declarations with the introduction of let and const. But what about our old buddy var? It’s been around since the dawn of JavaScript time, and some devs still hold onto it like a trusty sidekick. However, times are a-changin’, and it’s crucial to understand why const has become the new sheriff in town for many developers.

var: The Old Guard

Back in the day, var was all we had. It’s function-scoped, which means it lives and dies within the confines of a function. But, if you declare a var outside of a function, it’s global, and that can lead to all sorts of shenanigans. Here’s a classic example of var in action:

function partyLikeIts1999() {
  for (var i = 0; i < 10; i++) {
    console.log('Party on, Garth!');
  }
  console.log('The value of i is:', i); // The value of i is: 10
}

partyLikeIts1999();

Notice how i is accessible even outside the loop? That’s because var doesn’t care about block scope, which can lead to unexpected results and bugs that are harder to trace.

const: The New Kid on the Block

Enter const, the cool, calm, and collected variable declaration that’s all about block scope. When you declare a variable with const, it’s locked down tighter than Fort Knox within the block it’s defined in. Here’s how const rolls:

function rockOutWithConst() {
  const message = 'No touching!';
  if (true) {
    const secret = 'I love const';
    console.log(secret); // I love const
  }
  // console.log(secret); // ReferenceError: secret is not defined
  // message = 'Try and change me, I dare you'; // TypeError: Assignment to constant variable.
}

rockOutWithConst();

In this jam session, secret is only known within the if-statement’s block. Try to access it outside, and you’ll get the cold shoulder with a ReferenceError. And don’t even think about reassigning a const variable; it’ll throw a TypeError faster than you can say “immutable”.

When to Use const and When to Stick with var

The general consensus in the modern JavaScript era is to default to const unless you have a good reason not to. Why? Because const provides predictability. You know that once you set a value, it’s not going to change, which is a blessing for debugging and understanding your code’s flow.

But let’s not throw var under the bus just yet. There are times when var might be what you need, especially if you’re working on legacy code or you need a variable that’s function-scoped for some reason. But those cases are becoming as rare as a unicorn sighting.

Now, let’s dive into some code to see const and var in action.

Code Samples Galore: const vs var

Let’s start with a simple example. Say you’re building a function to calculate the area of rectangles. You might be tempted to use var, but const will serve you better.

function calculateArea(length, width) {
  const area = length * width;
  console.log('Area:', area);
}

calculateArea(5, 4); // Area: 20
// area = 25; // Nope, can't do that outside the function

With const, there’s no risk of accidentally changing the area once it’s calculated. It’s a small function, sure, but it’s a gateway to good habits.

Now, what about a scenario where you might need to update a variable? That’s where let enters the stage, but let’s not get ahead of ourselves. We’re focusing on const and var for now.

Imagine a countdown function for a rocket launch. You might think var is the way to go because you need to update the countdown. But there’s a catch:

function initiateCountdown(start) {
  for (var i = start; i >= 0; i--) {
    console.log(`T-minus ${i}...`);
  }
  console.log(`i after loop: ${i}`); // i after loop: -1
}

initiateCountdown(5);

See that? Even after the loop, i lingers around like a party guest who doesn’t know when to leave. It’s a classic case of var being too clingy with its function scope.


Alright, we’ve covered some ground on const and var, and you’re getting the hang of why const is often the better choice. But wait, there’s more! We’ll dive into some edge cases, best practices, and yes, even some love for var in the second half of this article. Stay tuned, and keep your variables in check!

Embracing Immutability with const

One of the most powerful aspects of const is its promotion of immutability. In JavaScript, immutability can lead to safer and more predictable code. When you declare an object or array with const, you can’t reassign it, but you can still mutate its properties. Here’s what I mean:

const playlist = { genre: 'Hip Hop', songs: [] };

playlist.songs.push('Lose Yourself by Eminem');
playlist.genre = 'Rap';

console.log(playlist);
// { genre: 'Rap', songs: [ 'Lose Yourself by Eminem' ] }

// playlist = { genre: 'Jazz', songs: [] }; // This would throw an error

Even though playlist is a const, you can still change the contents of the songs array and the genre property. This is because the const keyword ensures that the variable playlist always references the same object, but the object itself can be modified.

The Case for var in Modern JavaScript

While const (and let) are generally preferred for their block-scoping and clarity, there are some scenarios where var might still be relevant. For instance, when dealing with legacy code that relies on var‘s hoisting behavior or when you’re in an environment where ES6 isn’t fully supported, and transpilation isn’t an option.

Additionally, var can be useful in a very niche case where you want a variable to have function scope rather than block scope, although such instances are quite rare in modern development practices.

Hoisting: var vs const

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their containing scope during the compile phase. The difference in hoisting between var and const is subtle but important.

var declarations are hoisted and initialized with undefined, meaning you can reference them before the actual declaration:

console.log(myVar); // undefined
var myVar = 'hoisted';

function doSomething() {
  console.log(innerVar); // undefined
  var innerVar = 'also hoisted';
}
doSomething();

const (and let), on the other hand, are also hoisted but not initialized, which creates a temporal dead zone until the line where they’re defined:

console.log(myConst); // ReferenceError: Cannot access 'myConst' before initialization
const myConst = 'not hoisted';

function doAnotherThing() {
  console.log(innerConst); // ReferenceError: Cannot access 'innerConst' before initialization
  const innerConst = 'still not hoisted';
}
doAnotherThing();

This behavior of const can prevent a class of errors that occur from using a variable before it’s declared.

Best Practices: const Over var

The JavaScript community has largely embraced the best practice of favoring const over var. This is because const provides a clearer contract that the variable should not be reassigned. It makes your code easier to reason about since you can trust that the value of a const won’t change through reassignment.

Here’s a quick cheat sheet:

  • Use const by default for all of your variables.
  • If you need to reassign a variable, use let.
  • Avoid var to prevent scope-related bugs, but understand its behavior for legacy codebases.

Conclusion

The introduction of const and let in ES6 has been a game-changer for variable declarations in JavaScript. While var has its place in the history of JavaScript, const offers a more predictable and safer way to declare variables that should not be reassigned.

As we continue to write modern JavaScript, it’s essential to keep in mind the benefits of const and var and to choose the right tool for the job. The key takeaway is to write code that is clear, predictable, and easy to maintain. By preferring const, you’re taking a significant step in that direction.

So, next time you’re about to type var, pause and think: can this be a const? Your future self, and your fellow developers, will thank you for it.