Let, Const, and Var: A Beginner’s Guide to Variable Declaration in JavaScript

Let, Const, and Var: A Beginner’s Guide to Variable Declaration in JavaScript

Photo by Pankaj Patel on Unsplash

An important feature of any programming language, including JavaScript, is the ability to store data in variables that our code can access later on in its execution. For years, JavaScript only had one way to declare variables: using the var keyword. Starting in ES2015 (a.k.a ES6) two new keywords were added to the spec that gives JavaScript not just more variety, but more predictability when using these variables. These keywords are let and const and have forever changed the way we write JavaScript

There is more to these three keywords than just declaring variables. Each one is treated differently depending on various circumstances. I thought it would be helpful to go over those nuances in this post.

JavaScript Types

Before we get into how to declare variables, I believe it is important to have a brief conversation on the JavaScript type system. No matter what some developers might try to tell you, JavaScript DOES have a type system. JavaScript’s type system is considered a “weak” type system and more specifically, a dynamic type system. When people say that JavaScript doesn’t have a type system, what they are really saying is that JavaScript is not “strongly” typed or, in other words, does not provide type safety.

There is a very good explanation on the differences between them at Wikipedia but in an attempt quickly summarize it: a strongly typed language, through various measures, will at least minimize, if not eradicate all errors caused by using the wrong data type where weakly typed languages do not and force the developer to write defensive code to protect themselves against type errors at run time.

This is important to know for the rest of this post because data types and variables go hand in hand and having at least a basic understanding of JavaScript’s type system is very important when talking about declaring variables.

(If you would like to write JavaScript in a strongly typed way, you can use TypeScript. TypeScript is a superset of JavaScript that transpiles back to vanilla JavaScript. Ultimately, JavaScript is still weakly typed at run time, but it adds a layer of safety at development time that can help you feel as the developer feel more confident in your code.)

How To Use Var, Let, and Const

As I said before, there used to be only one way to declare variables in JavaScript by using the keyword var. Here is an example of the minimum you need to declare a variable:

var age;

In the above example, we have declared a variable called age which means we told our code “Hey, I need someplace to store some data, I’ll tell you what it is later.” At this point, the code still doesn’t know what type the data will be all it knows is that you need some space and you want to call that space age when you use it.

One might ask, what would happen if we tried to use the variable after we declare it. Would it have a value? The answer is yes, it would have a value:undefined. This is because JavaScript when setting that variable aside puts a place holder value until you assign a value to it. That value is undefined, which is a specific JavaScript value and not just JavaScript’s way of saying it hasn’t been defined yet.

Now that we have the space, we can then use that space to save data. Here is an example of each of those steps:

var age;

console.log(age); // undefined

age = 12;

console.log(age); // 12

Now just because we assigned a number to our variable age, doesn’t mean it can’t be reassigned to another value and that value can be of any type. This is where JavaScript’s dynamic typing kicks in. It allows us to do stuff like this:

var age;  
age = 12;  
age = age + 2;  
age = "Hello, World!";  
age = false;  
age = null;  
age = undefinded;

We will talk more about this later, but basically JavaScript gives us enough freedom to shoot ourselves in the foot.

Before we go into the other two ways to declare variables, I think it is important to go over some other variations on declaring variables. The first is that you can both declare a variable and instantiate with a value at the same time, like this:

var age = 12;

The second is that you can declare as many variables in a single line as you want simply by separating each variable with a comma. One can instantiate a value or not, like this:

var age = 12, name, isOld = true;

In Modern JavaScript, we now have two additional ways to declare variables using either the let or const keywords. let is very similar to var in that, it lets you declare a variable and optionally instantiate it with a value. You can also do more than one at a time, just like var. We can rewrite the above example like this:

let age = 12, name, isOld = true;

The main difference between var and let is how they are impacted by scope and the unique JavaScript concept of hoisting, which we will go more into that in the next section.

The other keyword is const which is short for constant. const is unique in two ways. Firstly, you MUST instantiate a variable with a value when you use const and secondly, you cannot reassign the variable to a new value afterward. const also has the same scope rules as let

How Does Scope Impact Variables

Scope in JavaScript deserves a blog post of its own, but to quickly summarize: scope is kinda like an environment separated from the rest of the code. Variables declared in a scope are only available in that scope. Scope can be declared inside of another scope. A child's scope has access to the parent scope, but the parent does not have access to the child's scope nor to any of the sibling scopes if they exist.

What is considered scope depends on which keyword you use. Variables declared using var are considered to use the execution scope. The execution scope is typically the enclosing function, otherwise the global scope. This means that a variable declared using varinside a block, such as an if-block, are still available outside of the block like this:

function varTest(){  
   if(true){  
     var age = 12;  
   }  
   console.log(age) //12  
}  
console.log(age) //Throws Reference Error in strict mode

As you can see, despite age not being declared until inside the if block, it is still available after, but only within the body of the function.

let and const are block-scoped. Generally speaking, anything inside two curly braces{} is considered a block. Here is an illustration of that scope:

function letTest() {  
  let age = 12;  
  {  
    let age = 2;   
    console.log(age);  // 2  
  }  
  console.log(age);  // 12  
}

The other important difference is that variables declared with var are hoisted, but variables declared with let or const are not. Hoisting is a phenomenon that variable declarations, but not assignments are ‘hoisted’ to the top of the scope. Going back to our varTest function, it can be rewritten like this:

function varTest(){  
   console.log(age) //undefined  
   if(true){  
     var age = 12;  
   }  
   console.log(age) //12  
}

//the above is effectively this

function varTest(){  
   var age;  
   console.log(age) //undefined  
   if(true){  
     age = 12;  
   }  
   console.log(age) //12  
}

Despite the fact that the variable is not declared until the if block, JavaScript ‘hoists’ up the declaration to the top of the scope, the function body. Variables declared using let or const are not hoisted, even inside the block scope, and are only available after it has been declared in the code.

What Are Some Best Practices Regarding Variable Declaration

When declaring something as best practice, there are many opinions. There are, however, common things that most agree upon. First of all, you should no longer use thevar keyword to declare variables due to the less than intuitive way that JavaScript handles the declarations of those variables.

Second, unless you need to reassign a value to the variable, you should use const to declare variables. There is no technical benefits for using const over let except one important thing. It prevents the developer from reassigning a new value to the variable, ensuring that the value and data type stay the same and can be reliable to be the same.

Variables is an import part of anyone’s JavaScript code. Understanding the various ways to declare variables and why you use them in your code, will help you write code that is easier to maintain.

Did you find this article valuable?

Support Travis Waith-Mair by becoming a sponsor. Any amount is appreciated!