There is a pattern in JavaScript that we use all the time without noticing it: Closure!

A closure occurs when you use an outer variable in an inner block. Here is a simple example:

let count = 0;

function increment() {
	count++; // closure here!
	return count;
}

increment();

console.log(count); //==> 1

Closures can come in handy when you want to save a function’s state.

Say that you’re building a video game, and you have a function that applies teleportation to a given object in a 2D context:

function teleport(object, x, y) {
	object.x = x;
	object.y = y;
}

You want to be able to teleport objects in your game. But the possible amount of teleportation can vary. What you can do is create a function that returns a new function limiting the amount of time we call the teleport function:

function teleportNTime(n) {
	let count = 0;

	return function (object, x, y) {
		if (count === n) {
			console.log("can't teleport anymore!");
			return;
		}

		teleport(object, x, y);
		count++;
		console.log('count: ', count);
	};
}

const teleport2Time = teleportNTime(2);
const teleport3Time = teleportNTime(3);

Two variables represent the state of teleport2Time:

  • the argument we passed teleportNTime; which is n = 2.
  • the count variable

Here the state is saved because each time we teleport, we remember the count and the teleportation limit (n = 2).

const goku = { name: 'goku', x: 0, y: 0 };

teleport2Time(goku, 2, 4); //=> count: 1
teleport2Time(goku, 8, 10); //=> count: 2
teleport2Time(goku, 0, 0); //=> can't teleport anymore!

Notice that the state of teleport3Time is independent of teleport2Time.

teleport3Time(goku, 2, 4); //=> count: 1