Ioana Tiplea
Ioana's Blog

Follow

Ioana's Blog

Follow
Core JavaScript: Var vs. Let vs. Const

Core JavaScript: Var vs. Let vs. Const

Ioana Tiplea's photo
Ioana Tiplea
·Sep 7, 2022·

6 min read

Table of contents

  • About the series
  • Var
  • Let
  • Const
  • When to Use Which?
  • Practice

About the series

Core JavaScript is a series I'm writing that covers, as the name suggests, some of the core principles of JavaScript. It originally started as study or reference material for myself, but I decided to share it with the community in the hopes that it will prove useful for others.

This series is intended for beginner JavaScript developers, or more experienced developers in need of a refresher. I have a few topics planned out already, but I would love to hear from you if there are any topics in particular you would be interested to read about!


In this article, I will go over the different ways of declaring variables in JavaScript, their characteristics (redeclarability, reassignability, scope and hoisting), and when to use which. At the end there will be a few exercises to practice the concepts I talked about.

Below is a quick summary of the main characteristics of each variable declaration:

RedeclarableReassignableScopeHoisting
varglobal / functionhoisted, initialized
letblockhoisted, not initialized
constblockhoisted, not initialized

Var

Before ES6, var was the only option for declaring variables in JavaScript, but it came with a few problems. For example, var variables can be redeclared, which means that doing something like this is perfectly valid:

var name = 'Steve';
var name = 'Chris';

This is not an issue if you're doing it intentionally. The problem arises when you may not be aware that a certain variable has been declared already. This can lead to unexpected outputs, errors, bugs and headaches.

Another characteristic of var variables is that they can be reassigned, which means you can freely change their value after they've been declared.

var age = 28;
age = 30;

In terms of scope, var variables are either in the global scope (if they have been declared outside of a function) or in the function scope (if they have been declared inside of a function). We will talk more about scope in a future article, but if you would like to learn more about it now, check out this article on MDN.

var yellowFruit = 'banana'; // outside of function -> global scope

function f() {
  var redFruit = 'strawberry'; // inside of function -> function scope
}

console.log(redFruit); // ReferenceError: redFruit is not defined, because redFruit is not in the global scope

In terms of hoisting, var variables are hoisted to the top of their scope and initialized with the value of undefined. We will talk more about hoisting in a future article, but if you would like to learn more about it now, check out this article on MDN.

// What we write
console.log(favoriteSeason);
var favoriteSeason = 'spring';

// How it's interpreted
var favoriteSeason;
console.log(favoriteSeason);
favoriteSeason = 'spring';

Let

let solves one of the major issues that come with var: let variables are not redeclarable in the same scope (more on this later). You don't have to worry about accidentally creating bugs in your code by redeclaring a variable that has already been declared. Doing this for example is not allowed:

let name = 'Steve';
let name = 'Chris'; // SyntaxError: Identifier 'name' has already been declared

Just like var, let variables can also be reassigned.

let age = 28;
age = 30;

In terms of scope, let variables are block scoped. A block is any code written between a pair of curly brackets { }. Remember how let variables are not redeclarable in the same scope ? They are, however, redeclarable if they are in different scopes, as illustrated below.

let yellowFruit = 'banana';

if (true) {
  let yellowFruit = 'lemon';
  console.log(yellowFruit); // lemon
}

console.log(yellowFruit); // banana

In terms of hoisting, let variables are hoisted to the top of their scope, but they are not initialized. This means that you cannot use let variables before declaring them.

console.log(favoriteSeason);
let favoriteSeason = 'spring';  // ReferenceError: favoriteSeason is not defined

Const

Just like let, const variables can also not be redeclared.

const name = 'Steve';
const name = 'Chris';  // SyntaxError: Identifier 'name' has already been declared

Unlike both var and let, const variables can not be reassigned.

const age = 28;
age = 30;  // TypeError: Assignment to constant variable.

When it comes to Objects declared with const - the Object itself cannot be reassigned, but the individual properties within the Object can be.

const student = {
  name: 'Alice',
  age: 16
}

student.name = 'Kelly';  // works fine

student = {
  name: 'Susan',  // TypeError: Assignment to constant variable.
  age: 15
}

Just like let, const variables are block scoped.

const yellowFruit = 'banana';

if (true) {
  const yellowFruit = 'lemon';
  console.log(yellowFruit); // lemon
}

console.log(yellowFruit); // banana

Just like let, const variables are hoisted to the top of their scope, but they are not initialized.

console.log(favoriteSeason);
const favoriteSeason = 'spring'; // ReferenceError: favoriteSeason is not defined

When to Use Which?

For let and const, there are two main approaches regarding when to use which:

  1. Use let by default, switch to const when you need a variable to remain constant.
  2. Use const by default, switch to let when you need a variable to be reassignable.

What about var? The general consensus among JavaScript developers is that in modern JavaScript YOU SHOULD NEVER USE VAR, under any circumstances. var is simply worse compared to let and const, and there is no good reason to ever use it. Also, there's a chance your tech lead will hunt you down if they see var in your pull requests. 😄


Practice

What are the outputs of these code snippets?

  1. if (true) {
      var year = 2022;
      let model = 'Golf';
    }
    
    console.log(year)
    console.log(model)
    

    Answer:

    2022
    ReferenceError: model is not defined
    

    Reason: model is declared using let, which means its scope is restricted to the code block of the if statement. Trying to access it outside of its scope will cause an error. year is declared using var, which is not block scoped and therefore can be accessed outside of the if statement.

  1. for (var i = 0; i < 3; i++) {
      console.log('Looping...')
    }
    
    console.log(i);
    

    Answer:

    Looping...
    Looping...
    Looping...
    3
    

    Reason: In this case var is declared globally, therefore i is accessible outside of the for loop.

  1. for (let i = 0; i < 3; i++) {
      console.log('Looping...')
    }
    
    console.log(i);
    

    Answer:

    Looping...
    Looping...
    Looping...
    Uncaught ReferenceError: i is not defined
    

    Reason: Because let is block scoped, i is restricted to the for loop and cannot be accessed outside of it.


Thank you for reading the second article in my Core JavaScript series! If you found this useful, if you have anything to add, or if I made any mistakes - I would love to hear from you! I'm also very open to suggestions for future topics for the series. 😊

Expect to see the next part soon. Thanks and see you there!

 
Share this