DEV Community

Dennis van Dalen
Dennis van Dalen

Posted on • Edited on • Originally published at vandalen.dev

What is up with var, let and const

Assuming you know some JS basics

Let's start with the 'old' keyword var for declaring variables. var is top level (aka. global level). Let me show you what that means with an example.

function logName(setName){
  if(setName){
    var name = 'Dennis';
    console.log(name);
  } else {
    console.log(name);
  }
}
logName(true); // 'Dennis'

Returns Dennis as expected.

logName(false); // Undefined (?)

Why is this undefined? Shouldn't this return a ReferenceError? This is called hoisting. What JavaScript does is, it puts the var at the top level, so to say at the top of your code. You can read it as follows:

function logName(setName){
  var name;
  if(setName){
    name = 'Dennis';
    console.log(name);
  } else {
    console.log(name);
  }
}

Makes sense now right? If you read it like this it, we expect it to be undefined.

In JavaScript, a variable can be declared after it has been used.
In other words; a variable can be used before it has been declared.

~ w3schools


So this is where let and const come in play.

let and const are block level. A block is anything between the opening { and the closing }

function logName(setName){
  if(setName){
    let name = 'Dennis';
    console.log(name);
  } else {
    console.log(name);
  }
}
logName(true); // 'Dennis'

Returns Dennis as expected.

logName(false); // Uncaught ReferenceError: name is not defined

Reference error! This is what we want :) Because we don't expect the variable name to exist at all.


const .. vs .. let

A const can not be reassigned, but is not immutable. You can still alter it, for example: take an array, you can still push and pop, but not reassign to a new array. Let's take a look at what happens.

Re-assigning a const:

const names = ['Dennis', 'Daan'];

names = ['Harry', 'Faye'];

console.log(names);
Uncaught TypeError: Assignment to constant variable

This doesn't work. We get a type error. We can not reassign a const.

But, only the initial assignment is immutable. We can still change the values of the array.

Updating the value of a constant:

const names = ['Dennis', 'Daan'];

names.push('Harry');
names.push('Faye');

console.log(names);

(4) ["Dennis", "Daan", "Harry", "Faye"]

No more reason to use var?

If you have been writing correct code, you will probably be able to turn all var statements into let statements without any semantic changes.

let is preferable because it reduces the scope in which an identifier is visible. It allows us to safely declare variables at the site of first use.

const is preferable to let. Unless you need to mutate a reference, use a const declaration. This has all the benefits of let along with reducing the presence of uninitialized variables and making code generally easier to reason about. If you aren't sure if you will need to mutate a reference, declare it const until you find yourself explicitly needing to do so.

~ Aluan Haddad


When to use what?

I'm not saying everyone should stick to the following strategy, but this seems to be working for me:

  • Default to const
  • Switch to let if you need to change the value
  • var can be used in the top level. But not that useful, you can also put a let at the top if you want this behaviour.

Oh, and you can use: Object.freeze() → if you want it to be immutable.

This is my first blog! Please let me know if you have feedback :)

Top comments (4)

Collapse
 
wesleysmits profile image
WesleySmits

Hi Dennis,

Great first post! Way too much confusion about the differences between var/let/const going around.

Just wanted to point out a small mistake in your post. var declarations aren’t hoisted to the global scope neccessarily. They’re hoisted to the top of their scope which is function-based.

So in your example the variable name would have been hoisted to the top of the function (above the if-statement) and not out of the function.

I use the same approach regarding defaulting to const and using let when the value needs to be changed. Although i’m quite sympathetic to Kyle Simpsons approach of using var by default and using let whenever you specifically want a block-scoped variable and const when you want to express that the value should not be changed.

This makes it more clear to other developers (including future-us) what the intention of the code is.

Thanks for the great read!

Collapse
 
dennisvdalen profile image
Dennis van Dalen

Thanks! Fixed it in the post :)

Collapse
 
aritdeveloper profile image
Arit Developer

Welcome to DEV Dennis! Great first post!

Collapse
 
uditvis profile image
Udit Agrawal

Great Post Dennis. Loved it and clear crisp. Beautiful....