HTML Academy
Becoming Independent
Getting to know events20/25
Back to the list of tasks
  • 1. Introduction to events
  • 2. How to add a handler
  • 3. How events are arranged
  • 4. Default actions
  • 5. Please pass the function
  • 6. Hiding the popup
  • 7. Pressing a key
  • 8. Choosing a key
  • 9. With one click
  • 10. Summary of “Events in JavaScript”, part 1
  • 11. First program: “Don’t be shy”
  • 12. Welcome to our photo gallery
  • 13. Click ’em all!
  • 14. Adding an image
  • 15. A bug has crept into the system
  • 16. Scope
  • 17. Global scope
  • 18. Inside out variables
  • 19. Becoming Independent
  • 20. Closures
  • 21. Let’s prepare for school
  • 22. Fixing the gallery
  • 23. Getting to the heart of the matter
  • 24. Summary of “Events in JavaScript”, part 2
  • 25. The Second Program: “Señor Tomato”
Let’s prepare for school
  • Sign up
  • Log in

Loading…
Everything will be ready in few seconds

  • Theory
  • Theory
  • Comments

Closures

The code really works. What is the secret behind this strange code, and what does it really even mean?

var collectContainer = function () {
  var food = 'pasta';
  var eatDinner = function () {
    console.log('I ate ' + food);
  }
  return eatDinner;
};

var schoolkid = collectContainer();
schoolkid();
// Outputs: I ate pasta.

We want the function to receive a recorded value that does not depend on changes in the global scope. Moreover, we do not want to obtain the result of the function immediately. It is the same thing with events, where we create a handler, but we don’t expect the event to be executed immediately. In our example, we are assembling a lunchbox of food for our student so that he will be able to dine on his favorite pasta regardless of what is being served in the cafeteria.

The code from the example works as follows: We call collectContainer. → The collectContainer function returns eatDinner. → We calleatDinner.

We create a function inside another function. Thus, we create one scope inside a different scope. eatDinner has its own scope that calls the food variable. This variable is declared inside collectContainer, which has its own scope.

If the eatDinner function does not find a food variable that was created within its scope, it looks in an adjacent scope (in the collectContainer scope) There it finds the food variable, learns that its value is equal to the string 'pasta', and records this value to memory.

But wait a minute! We output the schoolkid variable to the console, and yet we didn’t see any pasta there!

var collectContainer = function () {
  var food = 'pasta';
  var eatDinner = function () {
    console.log('I ate ' + food);
  };
  return eatDinner;
};

var schoolkid = collectContainer();
console.log(schoolkid);
// Outputs: function () { console.log('I ate ' + food); }

Everything is true. The code of the function itself does not change. It is simply that the value of the variable that existed when this function was declared is stored in the memory together with the function. Therefore, eatDinner is able “to remember” the value of food. This is a special feature of functions. They are able to remember their environment at the time they are created. In this case, they indicate closure. A closure is a function that remembers its surroundings. In other words, it is a function + all of the values of the variables outside of the local scope of this function. We are talking only about the variables the function uses in its code.

In our example, the eatDinner function together with the food variable are closures.

It is due to the closure that the code from the example above works. eatDinner remembers the value of food at the time of its creation. Therefore, it uses this value at the time it is called. It is as if our Mom was reminding us to buy potatoes as we walked past the store. When this happens, we remember the potatoes and go about doing our chores. When we saw the store, we remembered that we needed to get potatoes, so we purchased them and went home.

Make sure that the closures allow the student to eat pasta from his lunchbox regardless of the food that is being served in the cafeteria.

Comments

  • script.js
JavaScript
var food = 'salad'; var collectContainer = function () { var food = 'pasta'; var eatDinner = function () { console.log('I ate ' + food); }; return eatDinner; }; var schoolkid = collectContainer();

What didn’t you like in this task?

Thanks! We’ll fix everything at once!

Console

The code has changed, click “Run” or turn autorun on.

Result

Goalscompleted
  1. Below, call the function from this variable after the schoolkid variable is created.
  2. Then below it redefine the value of the global variable food to 'beef bullion'.
  3. Then call the schoolkid function again.

Cookies ∙ Privacy ∙ License Agreement ∙ About ∙ Contacts ∙ © HTML Academy OÜ, 2019−2025

VISAMastercard

Log in

or

Forgot your password?

Sign up

Sign up

or
Log in

Restore access

Have you forgotten your password or lost access to your profile? Enter your email connected to your profile and we will send you a link to restore access.

Forgot to connect your email to the profile? Email us and we’ll help.