Scope: IIFEs and Closure

Basics of JavaScript Scope

Due to the event-driven nature of JavaScript, scope is handled differently in order to facilitate the manipulation and transfer of scope, maintaining references outside of original scope, or overriding it when necessary. Let's consider the code snippet below. Press F12 to open your browser's developer tools. Then click "Try it out!" to run the code, and observe the output in the console. You should see output of "0 0 1", rather than the otherwise-expected "0 0 1 1 0 1". This is because the variable "i" within the inner for-loop overrides the value within the outer for-loop.

console.clear(); for (var i = 0; i < 2; i++) { console.log(i); for (var i = 0; i < 2; i++) { console.log(i); } }

IIFEs (Immediate-Invoked Function Expressions) can be used to create and immediately call a function in order to establish explicit scope boundaries, as shown below. An additional advantage of this is that certain arguments within the function can be defined at the end of the call and applied using generic variables (such as 'n' below) within the IIFE.

console.clear(); (function(n) { for (var i = n; i < 2; i++) { console.log(i); (function(n) { for (var i = n; i < 12; i++) { console.log(i); } })(10); } })(0);

Closure involves creating a reference to a variable value that can then be pulled out of the originating scope. In the example below, an instance of staticValue is set when getClosure() is called, and this instance is accessible by the function that is returned. The value is remembered and manipulated by future calls of the returned function, even when used outside of the scope of the function that generated it. This is useful in that it allows the creation of semi-global variables that can be accessed within a large instantiated scope (such as in a single-page app) without relying on the global scope. There are a variety of other event-driven advantages to being able to package functions and references in this way.

function getClosure(staticValue) { return function (step) { staticValue += step; return staticValue; }; } var returnedFunctionA = getClosure(0); var returnedFunctionB = getClosure(0); console.log(returnedFunctionA(1)); console.log(returnedFunctionA(2)); console.log(returnedFunctionB(10)); console.log(returnedFunctionB(20));

Recommended next: JSON: JavaScript Object Notation