what are closures

A closure is when a function can access its scope even if the function is executed outside of it.

examples of closures

The JavaScript timer function could be used as an example of closure.

JavaScript

function addSnackbar (text) {
  // createSnackbar() show a Snackbar on the screen
  const Snackbar = createSnackbar(text);
  setTimeout(function () {
    Snackbar.remove();

    console.log(`Snackbar '${ text }' was removed`);
  }, 1000);
}

addSnackbar('a new todo was added');
// Snackbar 'a new todo was added' was removed

Once addSnackbar() is executed and a second later passes it will still remember the variables text and Snackbar because of closures.

Another exampe of a closure could be the addEventListener() method because it takes in a function that can be executed later.

JavaScript

function addEventListenerToButton () {
    const addedAt = new Date();

    document.querySelector('.button')
        .addEventListener('click', function () {
            console.log(addedAt);
        });
}

addEventListenerToButton();
// the date the event listener was added at when the button is clicked

This is a closure because you never know when the button is going to be clicked and it will always print in the console the addedAt date.

Another example of a closure is wrapping a setTimeout() method in an IIFE inside a for loop.

JavaScript

for (var i = 1; i <= 5; i++) {
  (function (currentI) {
    setTimeout(function () {
      // currentI can still be access even though it is executed later
      console.log("i: " + currentI);
      // i: 1, i: 2, i: 3, i: 4, i: 5
    }, currentI * 1000);
  })(i);
}

This is a closure because currentI is stored in the scope of the IIFE and currentI is referenced inside the setTimeout() call.

If you don’t understand what IIFEs are there is an explanation later on.

Another example of closure is returning a inner function from an outer function while the inner function references a variable from the outer function.

JavaScript

function add (x) {
  return function (y) {
      return x + y;
  }
}

In the add()function the x parameter is passed in and it is use within a new function that is being returned.

In the returned function no where in it x is defined.

Variables are remembered if they are reference even after the function is returned.

JavaScript

function add (x) {
  return function (y) {
      return x + y;
  }
}

const add10 = add(10);
// returns a function with x set to 10

console.log(add10(5));
// 15

console.log(add10(20));
// 30

When the add() function is executed with 10 passed in it will set x to 10 and return a function that takes in a y parameter that returns x + y.

Now we can add 10 to any number by calling add10 with any number passed in.

x is remembered because of closures.

what is a immediately invoked function expression

note: also known as IIFE

This is how a IIFE looks like

JavaScript

(function () {
  // these variable will not exist
  // after console.log is executed
  let number = 42;
  const fruit = 'oranges';

  console.log('hi');
})();
// console log hi

Why use IIFE

conclusion

A closure is a function that can use variables declared around it even when it is executed outside the scope it was created in.

css
What is the CSS Box Model

Each element on a web page takes up space, and the box model describes the space around the element.

javascript
JavaScript Objects

Objects are containers that encapsulate data - meaning all of the relevant data and functions for the thing that the variable name represents are kept together in a 'capsule', better known as an object that can be created and manipulated in our programs as a single unit.