November 8th, 2017

Scope & Hoisting in JavaScript


JavaScript has quickly become one of the languages I use the most (probably second behind Java). Many people use JavaScript along with one of its many frontend frameworks (JQuery, AngularJS, etc.) without really knowing how the core language operates. I don't want to be one of those people!

This is my first of many discovery posts on JavaScript. Let's look at one of the basic concepts of the language: how variables interact with scope. Scope describes the area of a program where a variable is accessible (e.g. a variable declared in a function is only accessible within that function). Scope is also the execution environment for each line of a program. It consists of the variables and functions a program line is aware of. In JavaScript, scope can get a bit tricky.

One tricky part is that declared variables in JavaScript get hoisted to the top of their scope. Let's look at a quick code snippet.; // Error?? var x = 10;

For a Java developer like myself, I initially expected an error here. Variable x hasn't been declared yet on line 1. However, JavaScript returns undefined, which means the variable was declared but not initialized to a value.

What happened is JavaScript split the statement var x = 10 into its declaration and assignment. It then ‘hoisted' the declaration to the top of the scope (in this case the global program scope). When is invoked, JavaScript is already aware of var x. Tricky JavaScript!

If you are using ES6+ and don't want hoisting, you can use the let keyword (simply replace var with let in the previous example). Now if you run the code again, invoking will throw an error.

Here is one more basic example:

{ let firstName = "Andy"; var lastName = "Jarombek";; // Andrew; // Jarombek }; // Jarombek; // Reference Error

In JavaScript you can define a block scope with curly bracket syntax - { }. In this code, the variable defined with let is only available within the block scope, while the variable defined with var is exposed to the global scope1. let is useful when you want to constrain a variable to one small piece of code.

One thing that JavaScript block scope made me question was 'are variables defined with var in functions available globally?' The answer is NO (thankfully) so your internally defined function variables are local and safe!

You can check out the full code for these examples on GitHub, along with a look at how variables in for loops leak into the global scope (Yuck! – but there is a solution with let).

[1] Kyle Simpson, You Don't Know JavaScript: Scope & Closures (Beijing: O'Reilly, 2014), 36