Scope and Closures

To understand closures you must first understand scope since all a closure is in JavaScript is a situation where it looks like a variable should now be out of scope but where it is actually still in scope. Once you understand how scope works properly it becomes obvious how closures work.

From the beginning JavaScript has supported function level scope. A variable declared (using "var") inside a function has scope within the function. Once the function finishes running the variables defined inside the function generally go out of scope and are no longer accessible. Modern JavaScript also supports block scope (using "let") where a variable's scope is limited to the block of code it is declared in.

You can enforce that all variables are actually defined in their intended scope by specifying the "use strict"; command at the top of the function. This generates a syntax error if you try to use a variable that hasn't been declared. Early JavaScript used to pollute the global namespace with variables that you forgot to declare instead of giving a syntax error. You rarely need to use the global namespace in modern JavaScript with the main exception being to pass a library reference from the library script into your own script.

The simplest way to create your own scope for your script so as to not have the script interfered with by whatever may be polluting the global namespace is to wrap your code inside an IIFE (immediately invoked function expression). Typically an IFFE looks like this:

(function() {
"use script";
var x, y; // declare all the variables, functions and objects you want to use in this scope
// your code goes here

By using this wrapper around your code you have a complete list of all the variables functions and objects that your code uses all in one declaration at the start of the code and you know that there are no other variables being used in that code because if there were then you'd get an error for having forgotten to declare then. Of course the exception to this would be any variables that you declare using 'let' where they would only be in scope within the block where they are declared.

So what does this have to do with closures? Well a closure is created when a variable defined inside a function is still accessible even after the function where it was declared has finished running. While the variables defined inside a function generally go out of scope when the function finishes running this is only completely true when the function does not return a reference to another function nested within that function.

When you have functions nested one inside another the inner function not only has access to the variables declared at the top of that function, it also has access to all the variables declared at the top of the function it is nested inside of. Let's look at a simple example (note that the following code is incomplete and only includes those statements needed for the explanation).

outer = function() {
var a, b, inner;
inner = function() {
var c, d;
return c;
return inner;

In the above code we have two functions with the function inner() nested inside of the function outer() and both would be nested inside of our IIFE to keep them in our own script scope. The outer function declares a, b, and inner and so all of these exist to be able to be used within the outer function. The inner function declares a variable called c but because it is nested inside of outer the variables a and b are also in scope within the inner function.

With the inner function the variable d goes out of scope as soon as inner finishes running as at that point there is no way to reference d any more. The value in c is returned so while the variable itself goes out of scope the value of that variable remains accessible to subsequent code if the returned value gets assigned to a new variable. It would remain accessible for the scope of that new variable that it is copied to. So while the variables themselves are limited to function scope their values can live on if they are returned from the function.

The outer function returns the inner variable (in JavaScript the only difference between variables and functions is that functions are variables that can also be run to produce a different value). This means that the value of inner continues to exist even after outer has finished running.

The difference between returning a variable and returning a function is that we can not only reference a function, we can also run it. This is where the closure comes in because when you run a function it runs in the scope that it was declared in and not the scope you are running it in. When we run inner (via whatever variable we assigned to reference it via in the code that called outer) it runs in has access to the variables that were in scope at the time it was declared which includes not only the c and d variables declared within it but also the a and b variables defined in outer which therefore are still in scope within inner. The console.log statement will work because b is in scope whenever inner runs regardless of where it is run from.

Closures are simply another way of stating that in JavaScript uses declaration scope and not execution scope. The variables that are in scope when a function runs are those that were in scope when the function was declared.


This article written by Stephen Chapman, Felgall Pty Ltd.

go to top

FaceBook Follow
Twitter Follow