paint-brush
Simplified JavaScript: Hoistingby@MCapoz
1,122 reads
1,122 reads

Simplified JavaScript: Hoisting

by Mae CapozziOctober 23rd, 2017
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Hoisting remains one of the quirkier aspects of <a href="https://hackernoon.com/tagged/javascript" target="_blank">JavaScript</a>. When a <a href="https://hackernoon.com/tagged/developer" target="_blank">developer </a>declares a variable in JavaScript, that variable <em>behaves </em>as if it’s been lifted to the top of it’s available scope. This article isn’t going to concern itself with what actually happens behind the scenes to cause this behavior. Instead, I hope to provide a simple explanation of hoisting that will make sense to new users of JavaScript.

Company Mentioned

Mention Thumbnail
featured image - Simplified JavaScript: Hoisting
Mae Capozzi HackerNoon profile picture

Hoisting remains one of the quirkier aspects of JavaScript. When a developer declares a variable in JavaScript, that variable behaves as if it’s been lifted to the top of it’s available scope. This article isn’t going to concern itself with what actually happens behind the scenes to cause this behavior. Instead, I hope to provide a simple explanation of hoisting that will make sense to new users of JavaScript.

Hoisting in ES5

I went about 1.5 years without really understanding hoisting. I just stuck to a general rule — I always declared and assigned all of my variables at the top of the file. Before ES6 came out, that looked something like the code below:



var a = 1;var b = 2;var c = 3;



var adder = function (a, b, c) {return (a + b + c);};

adder(a, b, c); // Returns 6

The above code executes correctly and returns the number 6 when I run it. I declare and assign my variables at the top, then I define a function expression, and then I call my function, passing in the variables I’ve assigned earlier on.

But I get the same return value when I declare my variables at the top without assigning them, like this:



var a;var b;var c;



var adder = function (a, b, c) {console.log(a + b + c);};



a = 1;b = 2;c = 3;

adder(a, b, c); // Returns 6

Or I can call my function before I declare it, and I’ll still get 6 back:



var a = 1;var b = 2;var c = 3;

adder(a, b, c); // Returns 6



function adder(a, b, c) {console.log(a + b + c);};

Here’s a challenge. Before you keep reading, consider the code below and try to determine what it will evaluate to.

function hoist() {  a = 1;  var b = 2;}hoist();console.log(a); console.log(b);

Got it? OK, I’ll share the answer with you.

console.log(a) will return 1. On the other hand, console.log(b) will come back with `ReferenceError: b is not defined`. Both a and b are hoisted to the top of their scope, but because b was declared inside of the hoist() function, it’s not available to the global scope.

Hoisting in ES6

let and const introduce a different way of handling hoisting.

Let

We’ll start with let. In the example below, I’m trying to log the hoist variable, and then declaring and assigning it:


console.log(hoist); // ReferenceError: hoist is not definedlet hoist = 'hoisted';

In this case, I got a ReferenceError. This is different from what I would have gotten had I written var hoist = 'hoisted';. In that case, I would have ended up with undefined.

var and let throw different errors because JavaScript initializes them differently. When var is declared, JavaScript sets it to undefined. let, on the other hand, remains uninitialized. That way, it throws a helpful error rather than just returning undefined.

Const

Let’s try this with const:

console.log(hoist); // ReferenceError: hoist is not definedconst hoist = 'hoisted';

Like let, we get an explicit error telling us that hoist was not defined before it was called.

Functions

JavaScript will hoist function declarations, but not function expressions. I’ll provide some examples:

Function Declaration

If a function is declared but isn’t assigned to a variable, it will be hoisted to the top of it’s scope.

hoister(); // hoists



function hoister() {console.log('hoists');};

Function Expression

A function expression, on the other hand, will not be hoisted, so the below code returns a TypeError.

hoister(); // TypeError: hoister is not a function



var hoister = function () {console.log('hoists');};

Hopefully this post has helped you to make a bit more sense of hoisting. Of course, there’s always more to learn.

Let me know in the comments below if you have any questions, and please clap if you enjoyed this post!

Keep Reading