JavaScript Functions - Exercise 3

A closure keeps access to variables from its outer function even after that function returns.

javascript

function createCounter() {
  let count = 0;
  return () => ++count;
}
const counter = createCounter();
console.log(counter(), counter()); // 1 2

Recursion is when a function calls itself and stops at a base case.

javascript

function factorial(number) {
  if (number <= 1) return 1;
  return number * factorial(number - 1);
}
console.log(factorial(4)); // 24

bind creates a new function with a permanently selected receiver for ordinary function calls.

javascript

function introduce() {
  return `I am ${this.name}`;
}
const person = { name: "Ada" };
console.log(introduce.call(person)); // I am Ada

Arrow functions capture this lexically from the surrounding scope instead of creating a new receiver.

javascript

const user = {
  name: "Ada",
  showLater() {
    setTimeout(() => console.log(this.name), 0);
  }
};
user.showLater();

Composition combines small functions so the output of one becomes the input of another.

javascript

const double = (value) => value * 2;
const addOne = (value) => value + 1;
const result = addOne(double(4));
console.log(result); // 9

A generator returns an iterator and pauses at each yield until next() is called.

javascript

function* steps() {
  yield "first";
  yield "second";
}
const iterator = steps();
console.log(iterator.next().value); // first

Memoization caches results so repeated calls with the same input can avoid repeated work.

javascript

const cache = new Map();
function square(number) {
  if (!cache.has(number)) cache.set(number, number * number);
  return cache.get(number);
}
console.log(square(6)); // 36

Without a base case, recursive calls continue until the call stack overflows.

javascript

function countdown(number) {
  if (number === 0) return;
  console.log(number);
  countdown(number - 1);
}
countdown(3);