Understanding Var, Let and Const in JavaScript

Understanding Var, Let and Const in JavaScript

Introduction

There is more than one way to declare a variable in JavaScript, it uses the var, let, and const keywords for variable declarations and they all behave differently. I will try to explain them and their different behaviors but before I do that, I would like to explain some concepts that you will come across in trying to understand the various variable declarations, these are Scope and Hoisting.

Scope

The scope of a variable or function is the part of the code where the variable is visible or accessible. So it simply means variable access, that is, what variables do I have access to where the code is running. When a variable is not declared within a function, it is said to have a global scope, is assigned to the global object and can be accessed or referenced from anywhere. A variable declared within a function is said to have a local scope and can only be accessed inside the function.

var outside = "globally scoped"; //I am a global variable

function someFunction() {
    var inside = "locally scoped"; //I am a local variable
    console.log(inside); //This prints "locally scoped"
    console.log(outside); //This prints "globally scoped" as the variable is a global variable and can be accessed from anywhere
}

console.log(outside)//Still prints "globally scoped"
console.log(inside) //causes an error because the variable is not accessible from outside the someFunction function where it was declared

Hoisting

This suggests that before code execution all variable or function declarations are moved to the top of the code. Technically, they are put into memory but stay exactly where you typed them in your code. Hoisting allows you to use functions before you declare them, so you can doing something like this would be valid:

someFunction() function someFunction(){ //do something }

name = "Akin";
console.log(name);
var name;// Akin gets printed out, so the declaration gets hoisted

So now we can move on to the different methods of declaring variables in JavaScript.

Var

Var is traditionally function scoped, variable declared with var outside any function has a global scope and is visible everywhere. A variable declared with var inside a function is assigned to that function, it is local and is visible only inside the function just like a function argument or parameter. If a variable is declared in a function with the same name as a global variable, it takes precedence over the global variable, shadowing it. Var is function scoped not block-scoped so if you don't create a new function, you don't get a new scope, a block (identified by a pair of curly braces ({})) does not define a new scope, so things like if statements don't actually create a new scope. In JS all variables defined with the var keyword have an initial value of "undefined", this is due to hoisting which puts them in the memory with an initial value of undefined. Var is a less than ideal way to create a variable as you can redeclare a variable that has already been created and not get an error.

if(10 === 10){
    var name = 'Akin';
}
console.log(name);//will be able to access name

var setName = function(){
    var name = 'Akin';
}
setName();
console.log(name); //will return an error, won't be able to access the variable name because var is function scoped

var firstName = 'Akin';
var firstName = 'Goody'; //Redeclaring is valid when using var as it doen't return any error and this could cause a lot of problems

Let

This is a new way of declaring variables in JavaScript. It is the block-scoped version of Var. Block means anything surrounded by curly braces {}. So with let, things like if statements and for loops create new scopes. Defining a variable outside a function using let unlike var doesn't create a global variable. A variable declared using let can be reassigned just like with var but it can't be redeclared, trying to redeclare a variable created using let will return an error. like var, variables declared using let are also hoisted but uninitialized variables don't have an initial value of "undefined". With let, when you reference an uninitialized variable, you get a ReferenceError.

if(10 === 10){
    let name = 'Akin';
}
console.log(name);//will not be able to access name as let is block scoped

let setName = function(){
    let name = 'Akin';
}
setName();
console.log(name); //will return an error

let firstName = 'Akin';
let firstName = 'Goody'; //Redeclaring will cause an error using let

Const

This keyword is used to declare constants i.e. variables that are not going to change. Variables created using const can't be changed or reassigned to a different value. It doesn't provide immutability, it just makes sure that the reference can't be changed; that is to say, that with constant you can change the properties of the constant if it an object, you just can't reassign the variable. Const is block-scoped like let. If you have anything that isn't going to change, it should be a constant as it is a lot safer declaring it like that so that nobody assigns something else to the variable name. Const variables are also hoisted but not assigned as with let.

if(10 === 10){
    const name = 'Akin';
}
console.log(name);//like let, const  is also block scoped

const setName = function(){
    const name = 'Akin';
}
setName();
console.log(name); //will return an error as you are trying to access was defined in a different scope

const firstName = 'Akin';
const firstName = 'Goody'; //Redeclaring will cause an error using const
firstName = "Obi"; //Will return an error as you can't reassign a constant variable


const someObject = {
    name: 'Anton',
    age: 26
}
someObject.age = 28;
console.log(someObject.age); //Prints 28, as properties of an object declared with const can still be changed, the variable jsut can't be reassigned

Summary

Var is function scoped and an uninitialized var variable is assigned the value of undefined. Let and const were introduced in ES6, they are both block-scoped and can't be redeclared, trying to access an uninitialized const or let variable will return a ReferenceError. Variables declared with let can be reassigned but with const, they can't be.