AlgoDaily

JavaScript Functions

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

Introduction to JavaScript Functions

Introduction to JavaScript Functions

JavaScript functions play a crucial role in programming, enabling developers to create reusable blocks of code that perform specific tasks. They are essential for organizing and structuring code, improving code readability, and promoting code reusability.

A JavaScript function is a named block of code that can be executed by calling its name followed by parentheses. It can take in input values, called parameters, and return a value.

Here's an example of a simple JavaScript function that adds two numbers:

```js
// JavaScript code example

function addNumbers(a, b) {
  return a + b;
}

const result = addNumbers(3, 5);
console.log(result);
```

Introduction to JavaScript Functions Multiple Choice

Which of the following statements about JavaScript functions is true?

Function Declaration

Function Declaration

Function declaration is one of the ways to create a function in JavaScript. It involves using the function keyword followed by the function name and a pair of parentheses. You can also specify any parameters the function should accept inside the parentheses.

Here's an example of a function declaration that adds two numbers:

function addNumbers(a, b) {
  return a + b;
}

In this example, the function addNumbers takes two parameters a and b, and returns their sum. To call the function and use its result, you simply write the function name followed by parentheses and provide the necessary arguments.

const sum = addNumbers(5, 10);
console.log(sum); // Output: 15
```js
// Function Declaration

// Function declaration syntax
function addNumbers(a, b) {
  return a + b;
}

// Calling the addNumbers function
const sum = addNumbers(5, 10);
console.log(sum); // Output: 15
```

Function Declaration Multiple Choice

Which of the following is NOT a best practice for function declarations?

Function Expressions

Function Expressions

In JavaScript, function expressions are another way to define functions. Unlike function declarations, which use the function keyword, function expressions are created by assigning a function to a variable.

Here's an example of a function expression that adds two numbers:

const addNumbers = function(a, b) {
  return a + b;
};

In this example, we define a function expression called addNumbers that takes two parameters a and b and returns their sum. To call the function and use its result, we simply write the variable name followed by parentheses and provide the necessary arguments.

const sum = addNumbers(5, 10);
console.log(sum); // Output: 15

Function expressions are often used when we need to create functions dynamically or assign them as values to other variables or object properties.

Function expressions can also be anonymous, meaning they don't have a name. These are known as anonymous function expressions and are commonly used as callback functions or immediately invoked function expressions (IIFEs).

Anonymous function expressions are created without assigning them to a variable, just as shown below:

const greet = function(name) {
  console.log(`Hello, ${name}!`);
};
greet('John'); // Output: Hello, John!

Keep in mind that function expressions must be defined before they can be used, just like variables.

```javascript
const addNumbers = function(a, b) {
  return a + b;
}

const sum = addNumbers(5, 10);
console.log(sum); // Output: 15
```

Function Expressions Multiple Choice

What is one of the main differences between function declarations and function expressions in JavaScript?

Arrow Functions

Arrow Functions

In JavaScript, arrow functions provide a concise and streamlined syntax for defining functions. They are especially useful for writing shorter and more readable code.

Here's an example of an arrow function that calculates the square of a number:

const square = (num) => num * num;
console.log(square(5)); // Output: 25

Arrow functions can also have multiple parameters. Here's an example of an arrow function that calculates the sum of two numbers:

const sum = (a, b) => a + b;
console.log(sum(10, 5)); // Output: 15

Arrow functions can also have an implicit return if the function body consists of a single expression. Here's an example of an arrow function that checks if a number is even:

const isEven = (num) => num % 2 === 0;
console.log(isEven(6)); // Output: true

Arrow functions are a powerful tool in JavaScript and are widely used in modern code bases.

```javascript
// Arrow function example
const square = (num) => num * num;
console.log(square(5)); // Output: 25

// Arrow function with multiple parameters
const sum = (a, b) => a + b;
console.log(sum(10, 5)); // Output: 15

// Arrow function with implicit return
const isEven = (num) => num % 2 === 0;
console.log(isEven(6)); // Output: true

```

Arrow Functions Fill In

In JavaScript, arrow functions provide a ______________ syntax for defining functions.

Parameters and Arguments

Parameters and Arguments

In JavaScript, functions can accept inputs called parameters, which are defined in the function declaration. These parameters act as placeholders for data that will be passed to the function when it is called.

For example, consider a greet function that takes a name parameter and logs a greeting message:

function greet(name) {
  console.log(`Hello, ${name}!`);
}

In the example above, name is a parameter of the greet function. When the function is invoked with an argument, such as greet('Alice'), the value 'Alice' is passed as an argument and assigned to the name parameter within the function.

Try calling the greet function with different names as arguments:

greet('Alice');
// Output: Hello, Alice!

// Try calling the function with other names
```js
function greet(name) {
  console.log(`Hello, ${name}!`);
}

greet('Alice');
// Output: Hello, Alice!

greet('Bob');
// Output: Hello, Bob!

greet('Charlie');
// Output: Hello, Charlie!
```

Parameters and Arguments Fill In

In JavaScript, functions can accept inputs called ___________, which are defined in the function declaration. These parameters act as placeholders for data that will be passed to the function when it is called.

Return Statement

Return Statement

The return statement is used in JavaScript functions to specify the value that should be returned from the function when it is called. When a function encounters the return statement, it immediately exits and returns the specified value, if any.

In the example below, the calculateSum function accepts two parameters a and b and returns their sum:

function calculateSum(a, b) {
  return a + b;
}

const result = calculateSum(5, 10);
console.log(result); // Output: 15

In the code snippet above, the return statement is used to return the value of a + b back to the point where the function was called.

The return statement is crucial for retrieving values from functions and using them in other parts of your code. It allows functions to perform calculations or operations and provide the result for further processing.

Try modifying the calculateSum function to perform a different calculation and see how the return statement affects the result.


```js
function calculateSum(a, b) {
  return a + b;
}

const result = calculateSum(5, 10);
console.log(result); // Output: 15
```

Return Statement Multiple Choice

What does the return statement do in JavaScript functions?

Anonymous Functions

Anonymous Functions

In JavaScript, anonymous functions are functions that are declared without a named identifier. They are also commonly referred to as function expressions.

An anonymous function can be assigned to a variable or passed as an argument to another function. This allows for more flexibility and readability in code, as functions can be created and used directly where they are needed.

Example 1: Assigning an anonymous function to a variable
const add = function(a, b) {
  return a + b;
};

console.log(add(2, 3)); // Output: 5

In the example above, an anonymous function is assigned to the variable add. This allows us to call the function using the variable name, just like any other function.

Example 2: Using an anonymous function as an argument
setTimeout(function() {
  console.log('Hello, World!');
}, 2000);

In the above example, an anonymous function is passed as an argument to the setTimeout function. This delays the execution of the function inside setTimeout by 2000 milliseconds (2 seconds).

Anonymous functions are particularly useful in scenarios where a function is needed for a specific task and doesn't need to be reused or referenced elsewhere in the code. They provide a way to create functions on the fly, making code more concise and modular.

```js
// Example 1
const add = function (a, b) {
  return a + b;
}

console.log(add(2, 3)); // Output: 5

// Example 2
setTimeout(function () {
  console.log('Hello, World!');
}, 2000);
```

Anonymous Functions Multiple Choice

Which of the following statements is true about anonymous functions in JavaScript?

Higher-Order Functions

Higher-Order Functions

In JavaScript, functions are considered first-class citizens, which means they can be assigned to variables, passed as arguments to other functions, and returned from other functions. This powerful feature allows for the creation of higher-order functions.

A higher-order function is a function that accepts one or more functions as parameters and/or returns a function as its result. This means that higher-order functions can operate on other functions, treating them as data, and giving us the ability to write flexible and reusable code.

Example 1: Higher-order function accepting a function as a parameter

The following example demonstrates a higher-order function calculate that accepts two numbers as arguments, as well as another function operation. The operation function is then used to perform a calculation on the given numbers.

function calculate(a, b, operation) {
  return operation(a, b);
}

function add(a, b) {
  return a + b;
}

console.log(calculate(4, 5, add)); // Output: 9

In this example, the calculate function takes two numbers (a and b) and an operation function as parameters. The operation function is then used to perform the addition of a and b.

Example 2: Higher-order function returning a function

Another use case for higher-order functions is when a function returns another function. This can be helpful for creating reusable functions with different behavior based on some condition.

function createGreeting(language) {
  if (language === 'english') {
    return function(name) {
      console.log('Hello, ' + name + '!');
    };
  } else if (language === 'spanish') {
    return function(name) {
      console.log('¡Hola, ' + name + '!');
    };
  } else {
    return function(name) {
      console.log('Unknown language.');
    };
  }
}

const englishGreeting = createGreeting('english');
englishGreeting('John'); // Output: Hello, John!

const spanishGreeting = createGreeting('spanish');
spanishGreeting('Maria'); // Output: ¡Hola, Maria!

In this example, the createGreeting function returns a different greeting function based on the specified language. The returned function can then be invoked with a name to produce a personalized greeting.

Higher-order functions play a crucial role in functional programming paradigms and provide a way to write more modular, flexible, and reusable code. By treating functions as data, higher-order functions enable powerful patterns and techniques in JavaScript programming.

```js
// Example 1: Higher-order function accepting a function as a parameter
function calculate(a, b, operation) {
  return operation(a, b);
}

function add(a, b) {
  return a + b;
}

console.log(calculate(4, 5, add)); // Output: 9

// Example 2: Higher-order function returning a function
function createGreeting(language) {
  if (language === 'english') {
    return function(name) {
      console.log('Hello, ' + name + '!');
    };
  } else if (language === 'spanish') {
    return function(name) {
      console.log('¡Hola, ' + name + '!');
    };
  } else {
    return function(name) {
      console.log('Unknown language.');
    };
  }
}

const englishGreeting = createGreeting('english');
englishGreeting('John'); // Output: Hello, John!

const spanishGreeting = createGreeting('spanish');
spanishGreeting('Maria'); // Output: ¡Hola, Maria!
```

Higher-Order Functions Multiple Choice

Which of the following best describes a higher-order function?

Scope and Closure

Scope and Closure

In JavaScript, scope refers to the accessibility or visibility of variables, functions, and objects in some particular part of your code during runtime. The scope of a variable determines its lifetime as well as its visibility to other parts of your code.

Global Scope

Variables defined outside of any function are considered to have global scope. They can be accessed and modified from any part of your code, including inside functions.

Here's an example:

```js
// Example 1: Global Scope

let globalVar = 'I am a global variable';

function globalFunction() {
  console.log(globalVar); // Output: I am a global variable
}

globalFunction();
```

Scope and Closure Multiple Choice

Which of the following best describes the concept of scope in JavaScript?

Recursion

Recursion

In the context of programming, recursion is a technique where a function calls itself within its own body. This allows a function to solve complex problems by breaking them down into smaller, more manageable subproblems.

Recursion is often used when a problem can be divided into simpler instances of the same problem. By solving the simpler instances and combining the results, the function can achieve the desired outcome.

A classic example of recursion is the factorial function. The factorial of a non-negative integer n, denoted as n!, is the product of all positive integers less than or equal to n.

Here's an example of a recursive function that calculates the factorial of a number:

function factorial(n) {
  if (n === 0) {
    return 1;
  }

  return n * factorial(n - 1);
}

console.log(factorial(5)); // Output: 120

In this example, the factorial function calls itself with a smaller value of n until the base case (n === 0) is reached.

Recursion can be a powerful technique, but it's important to ensure that recursive functions have a well-defined base case and terminate eventually. Otherwise, the function may lead to infinite recursion and cause a stack overflow error.

```javascript
// Replace with a recursive function example relevant to the reader's interests and background

function countdown(num) {
  if (num <= 0) {
    console.log('Blast off!');
  } else {
    console.log(num);
    countdown(num - 1);
  }
}

// Example usage
countdown(5);
```

Recursion Multiple Choice

Which of the following best describes recursion in programming?

Immediately Invoked Function Expressions (IIFE)

Immediately Invoked Function Expressions (IIFE)

An Immediately Invoked Function Expression (IIFE) is a JavaScript function that is executed immediately after it is defined. It is a self-invoking function that encapsulates its code and executes it right away.

The syntax of an IIFE consists of wrapping an anonymous function inside parentheses, followed by an immediate invocation with a pair of parentheses.

Here's an example of an IIFE:

(() => {
  // IIFE code
})();

IIFEs are commonly used to create a private scope and isolate variables. Any variables declared within the IIFE are not accessible from the outside, providing a form of data privacy.

(() => {
  const privateVariable = "This is a private variable.";
  console.log(privateVariable);
})();

console.log(privateVariable); // Output: ReferenceError: privateVariable is not defined

In this example, the privateVariable is only accessible within the scope of the IIFE and cannot be accessed outside of it.

IIFEs are also useful for executing code once without cluttering the global namespace. They can be used to define modules or libraries without polluting the global scope.

(() => {
  // Module code
  const module = {};
  // Module functionalities
  module.function1 = () => {};
  module.function2 = () => {};

  // Expose module to the global scope
  window.module = module;
})();

In this example, the IIFE creates a module object with certain functionalities and exposes it to the global window object for other parts of the code to use.

IIFEs are a powerful tool in JavaScript to create self-contained code blocks, manage variable scope, and prevent namespace collisions. They are commonly used in modular JavaScript design patterns and help to improve code organization and maintainability.

```javascript
(() => {
  const player = "Kobe Bryant";
  console.log(`My favorite basketball player is ${player}.`);
})();

console.log(player); // Output: ReferenceError: player is not defined
```

True or False

IIFEs are used to create self-contained code blocks, manage variable scope, and prevent namespace collisions.

Pure Functions

Pure Functions

In functional programming, a pure function is a function that, given the same input, will always produce the same output and has no side effects. A pure function is independent of any mutable state or external context, which makes it predictable and easier to reason about.

Here are the characteristics of pure functions:

  • It always produces the same output for the same input.
  • It does not modify any data outside its scope.
  • It does not depend on any external state.
  • It does not produce any side effects.

Pure functions are like mathematical functions in that they only depend on their inputs and always produce the same result for the same inputs. This makes them highly testable and easy to debug.

Let's look at an example of a pure function:

function add(a, b) {
  return a + b;
}

The add function takes two parameters a and b, and returns their sum. No matter how many times you call this function with the same values of a and b, it will always return the same result.

Pure functions are also useful because they do not have any side effects. A side effect is any modification or interaction with the external world, such as changing a global variable or making an API call.

let counter = 0;

function increment() {
  counter++;
}

The increment function has a side effect of modifying the counter variable. Calling this function multiple times will change the state of the counter variable, making it harder to track and reason about.

By using pure functions, you can write code that is easier to understand, test, and maintain. Pure functions make functional programming paradigms more approachable and provide benefits like immutability, referential transparency, and easy debugging.

// replace with ts logic relevant to content
// make sure to log something
for (let i = 1; i <= 100; i++) {
  if (i % 3 === 0 && i % 5 === 0) {
      console.log("FizzBuzz");
  } else if (i % 3 === 0) {
      console.log("Fizz");
  } else if (i % 5 === 0) {
      console.log("Buzz");
  } else {
      console.log(i);
  }
}

True or False

Pure functions always produce the same output for the same input.

Default Parameters

Default Parameters

In JavaScript, default parameters allow you to specify a default value for a function parameter if no argument is provided when calling the function. This feature is particularly useful when you want to provide fallback values or handle cases where certain arguments are optional.

To define a default parameter in a function declaration, you can assign a value directly to the parameter when declaring the function. If an argument is not provided for that parameter when calling the function, the default value will be used instead.

Here's an example:

function multiply(a, b = 1) {
  return a * b;
}

console.log(multiply(5)); // Output: 5
console.log(multiply(5, 2)); // Output: 10

In the multiply function, the parameter b is assigned a default value of 1. When calling the function multiply(5), since the value of b is not provided, it will use the default value of 1. However, if you provide a value for b when calling the function multiply(5, 2), it will use the provided value instead.

Default parameters can be any valid JavaScript expression, including values, function calls, or even other variables. They are evaluated at the time the function is called.

Default parameters are especially helpful when dealing with optional arguments or when you want to provide sane default values for certain parameters.

```js
function multiply(a, b = 1) {
  return a * b;
}

console.log(multiply(5)); // Output: 5
console.log(multiply(5, 2)); // Output: 10
```

True or False

Default parameters allow you to specify a default value for a function parameter if no argument is provided when calling the function.

solution=true

Rest and Spread Operator

Rest Operator

The rest operator, denoted by three consecutive dots (...), allows a function to accept an indefinite number of arguments as an array. This is useful when you want to create a function that can handle varying numbers of arguments.

Here's an example of using the rest operator:

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3, 4)); // Output: 10
console.log(sum(5, 10)); // Output: 15

In the sum function, the rest parameter numbers captures any number of arguments passed to the function and converts them into an array. The reduce method is then used to calculate the sum of all the numbers in the array.

The rest operator is especially useful when you want to create functions that are flexible and can handle different numbers of arguments.

Spread Operator

The spread operator, also denoted by three consecutive dots (...), allows an array or iterable to be expanded into individual elements. It can be used in function calls, array literals, and object literals.

Here's an example of using the spread operator:

const numbers = [1, 2, 3, 4];
console.log(...numbers); // Output: 1 2 3 4

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const combinedArray = [...array1, ...array2];
console.log(combinedArray); // Output: [1, 2, 3, 4, 5, 6]

const object1 = { a: 1, b: 2 };
const object2 = { c: 3, d: 4 };
const combinedObject = { ...object1, ...object2 };
console.log(combinedObject); // Output: { a: 1, b: 2, c: 3, d: 4 }

In the first example, the spread operator is used to expand the numbers array into individual elements when passed to the console.log function.

In the second example, the spread operator is used to combine two arrays, array1 and array2, into a single array combinedArray.

In the third example, the spread operator is used to merge two objects, object1 and object2, into a single object combinedObject.

The spread operator is a powerful tool that allows you to easily manipulate arrays and objects in JavaScript by expanding them into individual elements.

```js
function multiply(a, b, c) {
  return a * b * c;
}

const numbers = [2, 3, 4];
console.log(multiply(...numbers)); // Output: 24
```

Rest and Spread Operator Multiple Choice

Which of the following is an example of using the rest operator in a function?

Callback Functions

Callback Functions

In JavaScript, a callback function is a function that is passed as an argument to another function and is invoked inside that function. Callback functions are commonly used in asynchronous programming to handle the results of asynchronous operations.

Here's an example of a callback function:

function greet(name, callback) {
  console.log(`Hello, ${name}!`);
  callback();
}

function sayGoodbye() {
  console.log('Goodbye!');
}

greet('John Doe', sayGoodbye);

In this example, the greet function takes two arguments: name and callback. It logs a greeting message with the provided name and then invokes the callback function. The sayGoodbye function is defined separately and passed as a callback to the greet function.

When the greet function is called, it logs the greeting message and then invokes the callback function, which logs 'Goodbye!'.

Using callback functions allows for more flexibility and control over the flow of asynchronous operations. They can be used to execute code after an asynchronous operation completes, handle errors, process data, and more.

```javascript
// Example of a callback function

function greet(name, callback) {
  console.log(`Hello, ${name}!`);
  callback();
}

function sayGoodbye() {
  console.log('Goodbye!');
}

// Passing a function as a callback

console.log('Before greet()');
greet('John Doe', sayGoodbye);
console.log('After greet()');
```

Callback Functions Fill In

In JavaScript, a callback function is a function that is passed as an argument to another function and is invoked inside that function. Callback functions are commonly used in asynchronous programming to handle the results of asynchronous operations.

Here's an example of a callback function:

function greet(name, callback) {
  console.log(`Hello, ${name}!`);
  callback();
}

function sayGoodbye() {
  console.log('Goodbye!');
}

greet('John Doe', ________);

In this example, the greet function takes two arguments: name and callback. It logs a greeting message with the provided name and then invokes the callback function. The sayGoodbye function is defined separately and passed as a callback to the greet function.

When the greet function is called, it logs the greeting message and then invokes the callback function, which logs 'Goodbye!'.

Using callback functions allows for more flexibility and control over the flow of asynchronous operations. They can be used to execute code after an asynchronous operation completes, handle errors, process data, and more.

Promises

Promises

Promises are a fundamental concept in JavaScript that allow us to handle asynchronous operations and avoid the callback hell. They provide a way to deal with asynchronous tasks in a more structured and readable manner.

A promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It has three states:

  1. Pending: The initial state of a promise before it settles.
  2. Fulfilled: The state of a promise when it has successfully completed the operation.
  3. Rejected: The state of a promise when it encounters an error or failure.

Promises can be created using the Promise constructor by passing a callback function with two parameters: resolve and reject. The resolve function is used to fulfill the promise, while the reject function is used to reject it.

Here's an example that demonstrates the basic usage of promises:

// Replace the example with a relevant explanation and code

const fetchData = () => {
  return new Promise((resolve, reject) => {
    // Simulating an asynchronous operation
    setTimeout(() => {
      resolve('Data fetched successfully!');
    }, 2000);
  });
};

fetchData()
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });
```js
// Replace the code below with a relevant example of Promises

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully!');
    }, 2000);
  });
};

fetchData()
  .then((data) => {
    console.log(data);
  })
  .catch((error) => {
    console.error(error);
  });
```

Promises Fill In

A promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. It has three states:

  1. Pending: The initial state of a promise before it settles.
  2. Fulfilled: The state of a promise when it has ______________ aysdfs.

Async/Await

Async/Await

Async/await is a more readable syntax for handling asynchronous operations in JavaScript. It allows you to write asynchronous code that looks and behaves like synchronous code, making it easier to understand and control the flow of execution.

The async keyword is used to define an asynchronous function, which can contain one or more await expressions. The await keyword is used to pause the execution of the function until a Promise is resolved or rejected.

Here's an example that demonstrates the usage of async/await to handle asynchronous operations:

// Using async/await to handle asynchronous operations

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully!');
    }, 2000);
  });
}

async function getData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

getData();
```js
// Using async/await to handle asynchronous operations

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully!');
    }, 2000);
  });
}

async function getData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

getData();
```

Async/Await Fill In

Async/await is a more readable syntax for handling ______________ operations in JavaScript.

Function Composition

Function Composition

Function composition is a technique used to combine multiple functions together to create more complex and reusable operations. It allows you to create new functions by chaining or nesting existing functions.

By using function composition, you can break down complex operations into smaller, modular functions. Each function performs a specific task and can be easily composed together to produce the desired result.

Function composition promotes code reusability and readability. It enables you to write code in a declarative style, where the flow of the code follows the logic of the problem domain.

Let's illustrate function composition with an example:

// Example: Function composition

function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

function multiply(a, b) {
  return a * b;
}

function divide(a, b) {
  return a / b;
}

function compose(f, g) {
  return function(x, y) {
    return f(g(x, y), g(x, y));
  };
}

const calc = compose(add, subtract);

const result = calc(10, 5);
console.log(result); // Output: 10

Function Composition Fill In

Function composition is a technique used to combine multiple functions together to create more ______________ operations. It allows you to break down complex operations into smaller, modular functions. Each function performs a specific task and can be easily composed together to produce the desired result.

Memoization

Memoization

Memoization is a technique used to optimize the performance of functions by caching their results. It involves storing the results of expensive function calls and returning the cached result when the same inputs occur again.

Memoization can be particularly useful when dealing with recursive functions that have overlapping subproblems. By caching the results of function calls, we can avoid redundant computation and improve the overall efficiency of the program.

Let's take a look at an example of memoization using the Fibonacci sequence:

// Using memoization to optimize the Fibonacci sequence

const memoize = (fn) => {
  const cache = {};

  return (...args) => {
    const key = JSON.stringify(args);

    if (cache[key]) {
      return cache[key];
    }

    const result = fn(...args);
    cache[key] = result;

    return result;
  };
};

const fibonacci = memoize((n) => {
  if (n <= 1) {
    return n;
  }

  return fibonacci(n - 1) + fibonacci(n - 2);
});

console.log(fibonacci(10)); // Output: 55
```js
// Replace with code relevant to memoization

function fibonacci(n) {
  if (n <= 1) {
    return n;
  }

  return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(10));
```

Memoization Swipe

Memoization is a technique used to optimize the performance of functions by caching their results.

Generating Complete

Generating complete for this lesson!

Open interactive view →