DEV Community

Molly Nemerever
Molly Nemerever

Posted on

Back to Basics - JavaScript Hoisting 101

It's always a good time to review the basics of your programming language! In this series I'll be reviewing some fundamentals of JavaScript. It is important that we refresh ourselves on how the language works behind the scenes and of course it is also great practice to be able to explain concepts in simple terms.

This week we review Hoisting - what it is, function and variable hoisting, and a few key takeaways.

What is Hoisting?

When your JavaScript code is compiled, variable and function declarations are "hoisted" to the top of their scope. Depending on where a variable is declared, the scope could be global or local. Either way, the variable declaration is hoisted to the top of that specific scope. Functions are also hoisted, but to the very top of the program. Functions are hoisted even above global variables. Hoisting is why you might see functions successfully called before they are declared - to make this possible they are pulled (hoisted) to the top of your program right before the code is executed.

It is important to note that when code is hoisted it is not physically relocated in your program. Instead, your program is scanned for all variable/function declarations and those relationships are saved in the lexical environment. Your code maintains its original formatting and structure while variable/function declarations are accessible via lexical environment.

Hoisting Functions:

  • Function Declarations are hoisted to the very top of the program. They can be called in the code prior to actual declaration. The example below logs without error:

function declaration hoisting example
function declarations hoisted to top of program

  • Function Expressions are not completely hoisted in the program. Instead, only the declaration will be hoisted because it is recognized as a variable (hint: var keyword). The actual assignment of the variable's value (in this case a function) is not hoisted. In the example below, you'll first get an error stating that expression is not a function. That is because the assignment was not hoisted - only the declaration. The second call of expression() works, because the program has parsed through the program ad reached the assignment of the function to var expression.

function expression hoisting example
declaration is hoisted, but not assignment of function value

Hoisting Variables:

Variables are hoisted to the top of their scope (local or global). Variables declared with var are hoisted slightly differently that variables declared with const or let.

  • var Variables are hoisted, initialized, but assigned value of undefined. Similar to function expressions only the declaration is hoisted, not the actual assignment of the variable's value. The code below demonstrates how var variables are hoisted, initialized with a value of undefined, and then reassigned their value once the program reaches the value assignment.

var variable hoisting example
hoisted, initialized, assigned undefined

  • let/const Variables are a little more tricky. These variables are hoisted, but remain uninitialized until they are evaluated. Unlike the var variables which are hoisted and initialized with a value of undefined, let/const variables are hoisted, but not initialized at all. That means they're sitting in the lexical environment uninitialized. Attempting to access a variable that is uninitialized throws a reference error. Once the program is in execution and reaches the variable declaration, your let/const variable will be initialized. It will either be initialized with a value (if assigned in the declaration line) or with undefined until a value assignment is reached later on in the code.

This can be rather confusing at first, so let's take a look at the example below. You'll see that first an error is thrown because while the variable exists in the lexical environment, it remains uninitialized until the program reaches the line of variable declaration. Line 11 the variable gets initialized, but is assigned a value of undefined because there is no value assignment. Line 13 the variable is assigned a value which overwrites previous value of undefined.

let const variable examples
hoisted, but initialized & assigned value once declaration is reached in code

Take a look at the example below which showcases let/var variables and their hoisting differences side by side:

compare contrast var let hoisting
note the difference in how var is hoisted and initialized and let is not

Key Takeaways!

  • Variable declarations are hoisted, while variable definitions are not.
  • Function declarations are hoisted, while function expressions are not.
  • Variables with var are hoisted, initialized, and assigned value of undefined
  • Variables with let/const are hoisted, but remain uninitialized until their variable declaration code is reached. Then, they are either assigned undefined or a value depending if value assignment exists.
  • It is helpful to declare your variables at the top of the function scope. This way, it is clear where variables are coming from and easier to identify their scope.
  • Declare and initialize your variables before use to avoid bugs which stem from incorrect hoisting assumptions.

Discussion (4)

Collapse
shogogan profile image
Victor Homem Heck

Nice article!
Just got confused with the var/let prints, had to test it to check how it works prefectly.

It would be nicer if the prints had the same lines, just changing var to let.

Aside of that, this helped me understand some things!

Thanks for sharing!

Collapse
mollynem profile image
Molly Nemerever Author

Great feedback, Victor! I think I'll add an additional image showing the same lines with var/let.

Collapse
ramalinga12prasad profile image
Ramalinga Prasad G S

Got the clarity about the function declaration and the function expression . Nice Article