Basic

Functions

Define reusable blocks of code with function declarations and arrow functions.

What you will see

3

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Define a function with a declaration and with an arrow, then build a closure that keeps its own private state alive across calls.

1

Write a function declaration that returns a templated greeting, then call it. Declarations are hoisted, so they can be used before their line appears.

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

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Hello, Ada!
Function declarations are hoisted to the top of their scope. The `return` sends a value back and stops execution.
2

Write short arrow functions for adding and squaring numbers. A single parameter needs no parentheses; the body is a single implicit expression.

const add = (a, b) => a + b; const square = n => n * n; console.log(add(2, 3)); console.log(square(4));

Before you run it, say out loud what it will print. Then open the answer.

What it prints
5 16
Arrow functions are concise but have no own `this`. Use them for callbacks and short expressions, not for methods that need `this`.
3

Capture a variable inside a returned function so it survives after the outer function finishes. Call the inner function twice and watch the private counter climb.

function counter() { let count = 0; return () => ++count; } const inc = counter(); inc(); inc(); console.log(inc());

Before you run it, say out loud what it will print. Then open the answer.

What it prints
3
A closure is a function that remembers its outer variables. It powers modules, memoization, and private state, but leaks memory if kept alive too long.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Arguments flow into a function; it computes and returns a value; closures capture outer state.
1 Call function with arguments
↓
2 Parameters receive the values
↓
3 Body runs and computes a result
↓
4 Return sends the value back to caller
Why this works
Hoisting and closures

Function declarations are hoisted to the top of their scope, so they can be called before their definition:

console.log(greet("Ada"));  // works even though defined below
function greet(name) { return `Hi ${name}`; }

A closure is a function that remembers variables from its outer scope even after the outer function returns:

function counter() {
  let count = 0;
  return () => ++count;
}
const inc = counter();
inc(); inc();   // 2 (count persists)

Closures power modules, memoization, and state isolation.

this binding

The value of this depends on how a function is called. Regular functions get this from the call site; arrow functions capture this lexically from where they are written:

const obj = {
  name: "Ada",
  label() { return this.name; },         // 'obj'
  arrow: () => this.name                 // outer this, not obj
};

Use arrow functions for callbacks (like setTimeout or array methods) where you want to preserve the surrounding this.

Examples

Function declarations

Declaring functions

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

A function declaration is hoisted: you can call it before it appears in the source. The return statement sends a value back to the caller and stops execution.

Arrow functions

Concise syntax

const add = (a, b) => a + b;
console.log(add(2, 3));   // 5

const square = n => n * n;   // single param, no parens needed
console.log(square(4));      // 16

Arrow functions are shorter but do not have their own this. Use them for callbacks and short expressions; use regular functions for methods that need this.

Default and rest parameters

Flexible arguments

function makeDrink(size = "medium", ...toppings) {
  console.log(`Order: ${size} with ${toppings.join(', ')}`);
}
makeDrink();                    // Order: medium with 
makeDrink("large", "cream", "ice"); // Order: large with cream, ice

Default parameters fill in when an argument is undefined. Rest (...) collects the remaining arguments into an array.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Loops and Iteration
Previous Lesson
Loops and Iteration
Next Lesson
Arrays and Objects
Arrays and Objects →