← Back to JavaScript series
πŸ› οΈ
Basics
Basics Β· Prerequisite: 04_Control_Flow

05. Functions Basics

Function declarations are hoisted, so you can call them above their definition. Function expressions and arrow functions are only usable after the variable is assigned. Arrow functions are short and have no `this` of their own, making them ideal for callbacks.

function declarationparametersscopehoisting
Duration
⏱ ~1.5 hours
Level
πŸ“Š Beginner
Prerequisite
🎯 Lecture 4
OUTCOME
Function declarations are hoisted, so you can call them above their definition. Function expressions and arrow functions are only usable after the variable is assigned. Arrow functions are short and have no `this` of their own, making them ideal for callbacks.

What you'll learn

  • 1Write function declarations, function expressions, and arrow functions.
  • 2Use default and rest parameters.
  • 3Distinguish between arguments and parameters.
  • 4Tell function scope and block scope apart.
  • 5Understand the idea of a pure function.

Overview

Function declarations are hoisted, so you can call them above their definition. Function expressions and arrow functions are only usable after the variable is assigned. Arrow functions are short and have no `this` of their own, making them ideal for callbacks.

Core Concepts

1. Declaration vs expression vs arrow

Function declarations are hoisted, so you can call them above their definition. Function expressions and arrow functions are only usable after the variable is assigned. Arrow functions are short and have no `this` of their own, making them ideal for callbacks.

javascript
function add(a, b) { return a + b; }     // declaration
const sub = function (a, b) { return a - b; }; // expression
const mul = (a, b) => a * b;             // arrow

2. Parameters and arguments

Parameters can have default values, and `...rest` collects a variable number of arguments.

javascript
function greet(name = "friend") {
  return `Hi, ${name}!`;
}
function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}

3. return and side effects

A function returns whatever you `return`, or `undefined` otherwise. A function that always produces the same output for the same input and changes no external state is called a "pure function".

javascript
// pure
const square = (x) => x * x;

// impure: mutates external state
let counter = 0;
const tick = () => { counter += 1; };

4. Scope

A variable is visible only within the block where it's declared. `let`/`const` are block-scoped, `var` is function-scoped. A function referencing variables from its surrounding scope is a closure (covered in detail later).

javascript
function outer() {
  const a = 1;
  if (true) {
    const b = 2;
    console.log(a, b); // 1 2
  }
  // console.log(b); // ReferenceError
}

Examples

FileWhat it covers
`01_declaration.js`Function declarations and hoisting
`02_expression.js`Function expressions and arrow functions
`03_params.js`Defaults, rest parameters, destructuring
`04_scope.js`Block vs function scope

src/01_declaration.js

javascript
/** Function declarations are hoisted β€” callable before their definition. */
console.log("3 + 4 =", add(3, 4));

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

/** Compute the area of a rectangle. */
function area(w, h) {
  return w * h;
}
console.log("area(5,6) =", area(5, 6));

src/02_expression.js

javascript
/** Compare function expressions and arrow functions. */
const sub = function (a, b) {
  return a - b;
};

const mul = (a, b) => a * b;

// Wrap an object literal in parens when returning it from an arrow
const wrap = (x) => ({ value: x });

console.log(sub(10, 3));
console.log(mul(4, 5));
console.log(wrap(42));

src/03_params.js

javascript
/** Combine defaults, rest parameters, and destructuring. */
function greet(name = "friend", greeting = "Hi") {
  return `${greeting}, ${name}!`;
}

function sum(...nums) {
  return nums.reduce((acc, n) => acc + n, 0);
}

function describe({ name, age = "?" } = {}) {
  return `${name} (${age})`;
}

console.log(greet());
console.log(greet("Ada", "Hi"));
console.log(sum(1, 2, 3, 4, 5));
console.log(describe({ name: "Linus" }));

src/04_scope.js

javascript
/** Show the difference between block scope and function scope. */
function demo() {
  const outer = "outside";
  if (true) {
    const inner = "inside";
    console.log(outer, inner);
  }
  // console.log(inner); // ReferenceError
}
demo();

// Closure preview: a function remembers the environment it was declared in
function makeCounter() {
  let count = 0;
  return () => (count += 1);
}
const next = makeCounter();
console.log(next(), next(), next()); // 1 2 3

Common Mistakes

  1. Forgetting that arrow functions don't have their own `this` and defining methods with them by accident.
  2. Forgetting that default parameter values only apply when the argument is `undefined`, then passing `null` and being surprised.
  3. Forgetting to `return`, then wondering why `undefined` comes back.
  4. Returning an object literal from a one-line arrow without wrapping it in parens (`() => ({ a: 1 })`).
  5. Letting a function silently mutate an outer variable, then losing track of where the change came from.

FAQ

Q1. Should I prefer declarations or expressions?

Top-level utilities read well as declarations; callbacks and small inline helpers are nicer as arrows.

Q2. What if my function has too many parameters?

Group them into a single options object. `function create({ name, age, role }) { ... }` uses destructuring.

Q3. Are functions values?

Yes β€” you can assign them to variables, pass them as arguments, and return them. We say JavaScript has "first-class functions".

Practice

  • `homework_01.js` β€” A function that takes a radius and returns the area and perimeter of a circle.
  • `homework_02.js` β€” A variadic function that averages its numeric arguments (including the empty case).

homework/README.md

## homework_01.js

  • Write a function that takes a radius `r` and returns `{ area, perimeter }`.
  • Use `Math.PI` and round to two decimal places (`Number(x.toFixed(2))`).

## homework_02.js

  • Write `average(...nums)` that averages an arbitrary number of values.
  • It must return `0` when called with no arguments.

homework/answer/homework_01.js

javascript
/** Compute the area and perimeter of a circle. */
function circle(r) {
  const area = Math.PI * r * r;
  const perimeter = 2 * Math.PI * r;
  return {
    area: Number(area.toFixed(2)),
    perimeter: Number(perimeter.toFixed(2)),
  };
}

console.log(circle(1));
console.log(circle(5));
console.log(circle(10));

homework/answer/homework_02.js

javascript
/** Average a variable number of arguments. */
function average(...nums) {
  if (nums.length === 0) return 0;
  const total = nums.reduce((acc, n) => acc + n, 0);
  return total / nums.length;
}

console.log(average());                  // 0
console.log(average(10));                // 10
console.log(average(1, 2, 3, 4, 5));     // 3
console.log(average(90, 80, 70));        // 80

Next Lecture

[06_Arrays_and_Strings](../../02_데이터_닀루기/06_λ°°μ—΄κ³Ό_λ¬Έμžμ—΄/) β€” Working with collections of data.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub β†—