Back to the roots - A var, let and const story

vladutcoman

vladutcoman

Posted on October 19, 2021

Back to the roots - A var, let and const story

An endless story, yeah? Oke, let's start with some introduction

If you ask someone why sometimes JS is so confusing, probably one of the reasons is var😩 declaration.

That was my experience too in 2017 when I had my first contact with JS. It was post-ES6(ES2015), which means the let and const were there.
I thought: "lucky me, var is history and now we live in a new era" πŸ™Œ. Guess what happened? Yeah, I was hit by a var bug in the face. TKO πŸ‘ŠπŸ˜΅, not stand a chance.

It's true that with ES2015 we have great alternatives for declarations in letπŸ”₯ and constπŸ”₯, but it is also important to know how var works (and pray we do not go into it πŸ™ ).

Now, why are let and const such a great option? Well, let's see! πŸ‘‡

Scope

πŸ‘‰ Let's try to understand it first: in a few words, scope represents where these variables are available for use.

  • var

Variables defined with var have global or function scope.

Global scope -> when they are defined outside any function and are available in the whole window

Function scope -> when they are defined inside a function and are available inside that function

var globalScope = 'global';

function varFcn() {
  var functionScope = 'function';
  console.log(globalScope); // -> 'global'
  console.log(functionScope); // -> 'function'
}

console.log(globalScope); // -> 'global'
console.log(functionScope); // -> Uncaught ReferenceError: functionScope is not defined
Enter fullscreen mode Exit fullscreen mode
  • let

Let declarations have block scope. What is a block? Well, a block is a code between {} - anything between curly braces is a block.

Here is a comparison example to better understand the difference:

var foodWithVar = 'salad';

if (true) {
  var drinkWithVar = 'beer';
}

console.log(foodWithVar); // -> 'salad'
console.log(drinkWithVar); // -> 'beer'

// Versus let declaration

let food = 'salad';

if (true) {
  let drink = 'beer';
}

console.log(food); // -> 'salad'
console.log(drink); // -> 'Uncaught ReferenceError: Can't find variable: drink'
Enter fullscreen mode Exit fullscreen mode
  • const

Is the same as variables declared with let.

Hoisting

πŸ‘‰ Hoisting is a Javascript voodooπŸ§™ where variables and functions declarations are moved to the top of their scope before the execution.

  • var

Besides being hoisted, the var variables are also initialized with undefined.

console.log(food); // -> undefined
var food = 'pizza';
console.log(food); // -> 'pizza'

// The code above is interpreted like this:

var food; // default value for var declaration is 'undefined'
console.log(food); // -> undefined 
food = 'pizza';
console.log(food); // -> 'pizza'
Enter fullscreen mode Exit fullscreen mode
  • let

Declarations with let are also hoisted, but unlike a var, they are not initialized with undefined.

console.log(food); // -> Uncaught ReferenceError: Cannot access 'food' before initialisation"
let food = 'pizza';
console.log(food); // -> 'pizza'

// The code above is interpreted like this:

let food; // let declaration has no default value
console.log(food); // -> Uncaught ReferenceError: Cannot access 'food' before initialisation"
let food = 'pizza';
console.log(food); // -> 'pizza'
Enter fullscreen mode Exit fullscreen mode
  • const

Is the same as variables declared with let.

Redeclaration and reassignment

  • var

❗ I will say just this: var variables can be redeclared! πŸ˜•

var food = 'pizza';
var food = 'salad';

console.log(food); // -> 'salad'
// This is madness! Who wants salad instead of pizza...?
Enter fullscreen mode Exit fullscreen mode

Also, vars can be reassigned.

πŸ‘‰ One thing I found out from a colleague is that in the pre-ES6 era, var redeclaration was used as a safety measure for controlling the value of the variable. Or to make sure the value is "clean". Seems like a nice hack, but also... strange, right?

  • let

Let variables can not be redeclared, but can be reassigned. πŸ₯³

// Redeclaration not working
let food = 'salad';
let food = 'steak'; // SyntaxError: Identifier 'food' has already been declared

// Reassignment is working
let drink = 'tea';
drink = 'beer';
Enter fullscreen mode Exit fullscreen mode
  • const

Const variables can not be redeclared nor reassigned.

const drink = 'tea';
drink = 'beer'; //TypeError: Assignment to constant variable.

const food = 'salad';
const food = 'steak'; // SyntaxError: Identifier 'food' has already been declared
Enter fullscreen mode Exit fullscreen mode

But here is something interesting: πŸ‘‰ if you have an object declared with const you can modify his properties.

const meal = {
  food: 'pizza',
  drink: 'cola'
};
meal.drink = 'pepsi';
meal.dessert = 'cake';
console.log(meal);
/*
{
  dessert: "cake",
  drink: "pepsi",
  food: "pizza"
}
*/

const meals = ['lunch'];
meals.push('dinner');
console.log(meals);
/*
["lunch", "dinner"]
*/
Enter fullscreen mode Exit fullscreen mode

Sort of conclusion

Look, I am not saying you should or should not use var. But, you need to be extra careful when using var because the math is not lying:
function scope + hoisting + redeclaration === 🀯

Don't believe me? Check this simple example:

var food = 'salad';

if (true) {
  var food = 'burger';
}

console.log(food); // -> 'burger'
Enter fullscreen mode Exit fullscreen mode

🚨 So, food was re-declared and modified. That is a real problem (besides having burgers all the time not being very healthy). If you have used food in other parts of the code, you could be surprised by the output you might get. That can cause a lot of bugs in the code.

That is just one of many examples of how wrong things can go when using var without knowing how it works. πŸ†˜

Also, var is common in legacy code. And if you don't know how let and const works, maybe it's easy to go with var. But, for me, let and const are the way to go and I encourage you to give them a try.

Well, I guess that's it for now. May the let-const be with you! Cheers 🍻

πŸ’– πŸ’ͺ πŸ™… 🚩
vladutcoman
vladutcoman

Posted on October 19, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Going from JS to TS
javascript Going from JS to TS

March 25, 2023

Javascript Array Filter Method
javascript Javascript Array Filter Method

October 17, 2022

Javascript Array Reduce Method
javascript Javascript Array Reduce Method

October 16, 2022

Transpilers vs Compilersβš™
javascript Transpilers vs Compilersβš™

January 12, 2022