Understand JavaScript Closures With Ease

»feb. 2 Last Year 135

Closures allow JavaScript programmers to write better code. Creative, expressive, and concise. We frequently use closures in JavaScript, and, no matter your JavaScript experience, you will undoubtedly encounter them time and again. Sure, closures might appear complex and beyond your scope, but after you read this article, closures will be much more easily understood and thus more appealing for your everyday JavaScript programming tasks.

This is a relatively short (and sweet) post on the details of closures in JavaScript. You should be familiar with JavaScript variable scope before you read further, because to understand closures you must understand JavaScript’s variable scope.

  • Receive Updates

What is a closure?
A closure is an inner function that has access to the outer (enclosing) function’s variables—scope chain. The closure has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function’s variables, and it has access to the global variables.

The inner function has access not only to the outer function’s variables, but also to the outer function’s parameters. Note that the inner function cannot call the outer function’s arguments object, however, even though it can call the outer function’s parameters directly.

You create a closure by adding a function inside another function.
A Basic Example of Closures in JavaScript:

function showName (firstName, lastName) {

var nameIntro = "Your name is ";
    // this inner function has access to the outer function's variables, including the parameter
function makeFullName () {
        
return nameIntro + firstName + " " + lastName;
    
}

return makeFullName ();

}


showName ("Michael", "Jackson"); // Your name is Michael Jackson


Closures are used extensively in Node.js; they are workhorses in Node.js’ asynchronous, non-blocking architecture. Closures are also frequently used in jQuery and just about every piece of JavaScript code you read.
A Classic jQuery Example of Closures:

$(function() {

var selections = []; 
$(".niners").click(function() { // this closure has access to the selections variable
selections.push (this.prop("name")); // update the selections variable in the outer function's scope
});

});

Closures’ Rules and Side Effects

  1. Closures have access to the outer function’s variable even after the outer function returns:
    One of the most important and ticklish features with closures is that the inner function still has access to the outer function’s variables even after the outer function has returned. Yep, you read that correctly. When functions in JavaScript execute, they use the same scope chain that was in effect when they were created. This means that even after the outer function has returned, the inner function still has access to the outer function’s variables. Therefore, you can call the inner function later in your program. This example demonstrates:

    function celebrityName (firstName) {
        var nameIntro = "This celebrity is ";
        // this inner function has access to the outer function's variables, including the parameter
       function lastName (theLastName) {
            return nameIntro + firstName + " " + theLastName;
        }
        return lastName;
    }
    
    var mjName = celebrityName ("Michael"); // At this juncture, the celebrityName outer function has returned.
    
    // The closure (lastName) is called here after the outer function has returned above
    // Yet, the closure still has access to the outer function's variables and parameter
    mjName ("Jackson"); // This celebrity is Michael Jackson

  2. Closures store references to the outer function’s variables; they do not store the actual value. 
Closures get more interesting when the value of the outer function’s variable changes before the closure is called. And this powerful feature can be harnessed in creative ways, such as this private variables example first demonstrated by Douglas Crockford:

    function celebrityID () {
        var celebrityID = 999;
        // We are returning an object with some inner functions
        // All the inner functions have access to the outer function's variables
        return {
            getID: function ()  {
                // This inner function will return the UPDATED celebrityID variable
                // It will return the current value of celebrityID, even after the changeTheID function changes it
              return celebrityID;
            },
            setID: function (theNewID)  {
                // This inner function will change the outer function's variable anytime
                celebrityID = theNewID;
            }
        }
    
    }
    
    var mjID = celebrityID (); // At this juncture, the celebrityID outer function has returned.
    mjID.getID(); // 999
    mjID.setID(567); // Changes the outer function's variable
    mjID.getID(); // 567: It returns the updated celebrityId variable

  3. Closures Gone Awry
    
Because closures have access to the updated values of the outer function’s variables, they can also lead to bugs when the outer function’s variable changes with a for loop. Thus:

    // This example is explained in detail below (just after this code box).
    function celebrityIDCreator (theCelebrities) {
        var i;
        var uniqueID = 100;
        for (i = 0; i < theCelebrities.length; i++) {
          theCelebrities[i]["id"] = function ()  {
            return uniqueID + i;
          }
        }
        
        return theCelebrities;
    }
    
    var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}];
    
    var createIdForActionCelebs = celebrityIDCreator (actionCelebs);
    
    var stalloneID = createIdForActionCelebs [0];

console.log(stalloneID.id()); // 103

    In the preceding example, by the time the anonymous functions are called, the value of i is 3 (the length of the array and then it increments). The number 3 was added to the uniqueID to create 103 for ALL the celebritiesID. So every position in the returned array get id = 103, instead of the intended 100, 101, 102.

    The reason this happened was because, as we have discussed in the previous example, the closure (the anonymous function in this example) has access to the outer function’s variables by reference, not by value. So just as the previous example showed that we can access the updated variable with the closure, this example similarly accessed the i variable when it was changed, since the outer function runs the entire for loop and returns the last value of i, which is 103.

    To fix this side effect (bug) in closures, you can use an Immediately Invoked Function Expression (IIFE), such as the following:

    function celebrityIDCreator (theCelebrities) {
        var i;
        var uniqueID = 100;
        for (i = 0; i < theCelebrities.length; i++) {
            theCelebrities[i]["id"] = function (j)  { // the j parametric variable is the i passed in on invocation of this IIFE
                return function () {
                    return uniqueID + j; // each iteration of the for loop passes the current value of i into this IIFE and it saves the correct value to the array
                } () // BY adding () at the end of this function, we are executing it immediately and returning just the value of uniqueID + j, instead of returning a function.
            } (i); // immediately invoke the function passing the i variable as a parameter
        }
    
        return theCelebrities;
    }
    
    var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}];
    
    var createIdForActionCelebs = celebrityIDCreator (actionCelebs);
    
    var stalloneID = createIdForActionCelebs [0];
    
console.log(stalloneID.id); // 100
    
    var cruiseID = createIdForActionCelebs [1];
console.log(cruiseID.id); // 101

Six Courses Coming Soon (Updated)

Don't learn JavaScript, Meteor, Node, Backbone, or any other web-dev technologies until you see our course offering or at least until you use our Modern Developer Technology Guide to determine which specific set of technologies you need to learn and use to accomplish your goals. Both are coming soon.

Get a Complete Web-Dev Education

Each course is part of a Career Path, a complete web dev education. About 3 to 6 courses make up a Career Path. Note the following Career Paths you can choose from:

  • jQuery Developer/Designer, Junior Front-end Developer, Web Developer, or JavaScript Developer (2 courses)
  • The Modern Front-end Developer (3 courses)
  • Designer to Developer: Designer Building a Startup (3–4 courses)
  • The Front-end-Framework-Equipped Modern Front-end Developer (4 courses)
  • Full-stack Modern Developer (4–6 courses)
  • Startup-Bound Developer (Build complex database-driven startups like Facebook and Twitter) (4–6 courses)
  • HTML5/JavaScript Mobile Developer (Build mobile apps for Android and iOS using your JavaScript skills)
  • iOS Developer (Build native iPhone/iPad apps)

First Ever JavaScriptIsSexy.com Courses

In a few weeks, look out for six comprehensive courses, unlike any you can find elsewhere online. Our Career Paths provide the best value—more comprehensive (we teach you everything), more relevant (latest and most apt technologies), and more affordable (~90% less than programming boot camps; ~99% less than college) than other similar courses, online or offline. You will learn more about modern web development (in 4–6 months) in our Career Paths than you would at any 4-year university.
  1. Course 1: Essential JavaScript and Modern Web Application Development

    You can't develop modern applications with just JavaScript.

    What You Will Learn
    In this course, you will learn beginning to intermediate JavaScript along with all the relevant and necessary technologies and tools to develop complete modern web applications on the front end. Note that JavaScript by itself is just about 35% of what you have to learn to develop modern web applications, even simple web applications.

    Who Is this Course For?
    — Anyone with at least some high school education
    — No programming experience necessary

    You will be able to develop complete moderately complex front-end web applications using JavaScript and other tools and technologies.

  2. Course 2: Mastering JavaScript and Modern Web Application Development

    Become a proficient modern JavaScript developer.

    What You Will Learn
    In this course, you will learn intermediate to advanced JavaScript along with all the relevant and necessary (intermediate to advanced) technologies and tools to develop complex modern web applications, though not database-driven apps.

    Who Is this Course For?
    — Completed at least the "essential" course

    What will graduating from this course allow you to do?
    Work as a jQuery Developer/Designer, Junior Front-end Developer, Web Developer, or JavaScript Developer. JavaScript and Web Developers with similar expertise can easily make $70,000 a year. (Salary varies by city and developer's expertise and experience.)

  3. Course 3: The Modern Front-end Developer

    Become a qualified Front-end Developer and make a huge salary or develop your own startup—if you take the "Skip-the-backend" course.

    What You Will Learn
    In this course, you will learn everything (except a specific front-end framework; see the next course) you need to learn to become a highly qualified Front-end Developer. You will learn not just JavaScript, but all the latest technologies and tools that modern front-end developers must know.

    Who is this course for?
    — Completed course 1
    — And graduated from course 2

    What Will Graduating from This Course Allow You to Do?
    Front-end developers are in high demand, perhaps more so than any other programmers, and they make more than $80,000 a year. (Salary varies by city and developer's expertise and experience.)

    We will prepare you for jobs and connect you with agencies and employers, when you graduate from the "Front-end Career Path."

    Of course you will be able to develop your own startup as well, if you take the "Skip the backend" course after this course.

  4. Course 5: Front-end-Framework-Equipped Modern Front-end Developer (Choose either React, Angular, Backbone, OR Ember)

    We will help you choose the best front-end framework for you. Don't waste time learning a front-end framework that's not for you.

    Advanced front-end developers with experience using at least one of the four noted front-end frameworks are undoubtedly the hottest (highly sought after) developers today. They make between $70K and $160K+. (Salary varies by city and developer's expertise and experience.)

  5. Course 6: The Modern Full-stack Developer

    Learn the technologies you need to know to become a qualified and successful full-stack JavaScript developer.

    What You Will Learn
    You will learn all the tools, skills, and technologies necessary to become a full-stack JavaScript developer.

    Who Is this Course For?
    — Completed the first three courses

    What Will Graduating from This Course Allow You to Do?
    You will be in high demand as a full-stack JavaScript developer, making between $70,000 and $160,000+ a year. You will be able to develop any kind of startup comfortably. (Salary varies by city and developer's expertise and experience.)

  6. Other courses are coming later, including a "Skip-the-Backend" course, courses on developing mobile apps for iOS and Android using JavaScript, and a course on developing iOS apps using Swift and other Apple technologies.

What Can You Do Right Now?

  1. First, enter you email in the "Receive Updates" form above.
  2. Then, use the Contact form to (a) request features, (b) make suggestions, or (c) ask questions. We want to make our courses the best courses, the best value, the most rewarding. We need your help to do that.

When Specifically Will the Courses Begin?

We will release the course web site, with more detailed information, in about 3–4 weeks (most likely in January). You can enroll in classes then.

The first set of courses may begin to roll out in February.

How Much Will Each Course Cost?

While we haven't finalized the cost for each course, I do know that we have different prices for the courses. For example, Course 1 will cost less than the Front-end course. Moreover, the cost per course will definitely be affordable to the working class. I will make certain the courses are affordable for most people. I will fight to keep Course 1 under $200, though I can't promise that I will win.

Get Ready! Between now and Christmas, enjoy the down time because, when our courses begin, they will kick your butt into web-dev shape. So get ready to work hard, build cool stuff, change the world (you will), and realize your dreams.

Leave a Reply

Current ye@r *