Javascript Hoisting: The Easy Guide
Introduction
There are probably millions of javascript developers out there, but only a handful of those understand the internal workings of the language and some advance concept such as hoisting.
The major reason for this is because you can write decent javascript code without an advanced-level knowledge of the language since all you need to write JS is knowing some of its syntaxes and you are good to go.
Another reason for this is that for people who do care, it's difficult finding learning materials that would break things down without complicating it further - at least, that was the barrier in my case. As a result of this, people just give up and leave the advance stuff to the StackOverflow lions to argue about.
Rather than give up, you should, however, try to master these things since knowing them would not only make you a better programmer but also save you a lot of time you would otherwise spend debugging your code and those written by others.
In this article, I will to explain what javascript hoisting is, why it is built into the language, and share some example code to explain it. I will also give some tips that would help you can do to avoid potential issues related to javascript hoisting.
This might be a long read, kindly bear with me.
Scopes and Variables: A Refresher
To understand hoisting, we need to understand scopes and variables in javascript.
Scope
A scope in programming refers to the visibility and accessibility of variables or methods in one part of your program to another.
The accessibility of a variable in any part of your code depends on the scope in which the variable exists in.
In javascript, the two types of scopes available are global and local.
The global scope have objects that are accessible to any part of your javascript program. In the browser environment, the global variables exist in what is known as the Window object while in NodeJS, all global variables exist in the global object.
The local scope in contrast, have objects that are accessible only in the context of their declaration.
Variable Declaration and Variable Assignment
This is how you declare and assign a variable value on the same line in javascript.
var myName = 'Olawale';
Only at the left-hand side of the expression var myName
is the variable declared while on the right-hand side, the declared variable is assigned (assignment) a value which in our case is Olawale
.
For the sake of convenience, variables can be declared and assigned on the same line.
They can also be done separately.
To simplify thing, I won't be explaining the initialization phase of the variable cycle which is done automatically by the javascript engine. It is, however, important that you understand the difference between declaration and assignment before proceeding.
Enough! What is Hoisting?
Hoisting in English language refers to the the process of raising a something up by use of a rope or pulley. An example is a country's flag being hoisted during national celebrations.
Hoisting refers to the process in which the javascript interpreter moves all functions and variable declarations to the top of the current scope (the scope in which the declaration occurred).
To understand this, here is what happens when you try to use an undeclared variable in javascript: You get a ReferenceError because myName
variable has not been declared.
In the image above, no declaration is done, and as such, the error makes sense, since the console.log is passed a value that does not exist.
Consider the image below:
Now, console.log claims the variable myName
exists, but it has an undefined value (note that undeclared is not the same as undefined). The reason for this is that when the interpreter goes through the file before the execution phase, the variable declarations are moved to the top, in effect, converting the file to something like this before it is executed.
var myName;
console.log(myName);
myName = "Olawale";
Essentially, moving the variable declaration to the top of the program before execution. It also makes sense that the value of myName
is undefined
because a variable declaration without an assignment in javascript will default to undefined
(It exists but is yet to be not defined).
Congratulations! If everything makes sense up to this point, then you already know what hoisting is. However, here are some additional things you need to know about hoisting in javascript.
Functions Declaration are Hoisted too
You must understand that not only variables declarations are hoisted in javascript. Function declarations (not expressions) are hoisted as well, and this is what makes the invocation of a function possible before its declaration, provided they exist in the same scope.
The interpreter moves the function declaration to the top of the scope, which is why the invocation would work before the declaration. It is, however, important to understand that while this would work for function declarations, it would not work for function expressions as those are not hoisted.
Hoisting and Scoping
Hoisting is done within the context of declarations, which is why the output of the console.log in the code from the image below would be undefined
, even though the myName
variable is declared and already assigned a value in the global scope.
The global variable myName
is being overwritten by the hoisting process occurring in the function scope since a declaration is happening on line 5.
Avoiding Bugs
While there are legitimate uses of hoisting, you can prevent this behaviour in your code to avoid unintended consequences due to the unintuitive nature of this feature.
With the introduction of javascript ES6 let
and const
keywords, variables can now be declared using these keywords which are block-scoped by default, and are not hoisted.