Chapter 8 of 28 · JavaScript for Beginners — Complete Free Tutorial

Functions in JavaScript

A function is a reusable block of code with a name (usually) that takes inputs and returns an output. Functions are the primary unit of organisation in JavaScript — you will write them constantly, in four main flavours.

Function declaration

function greet(name) {
  return `Hello, ${name}!`;
}

console.log(greet('Asha'));   // → Hello, Asha!

Declarations are hoisted whole — callable before their line runs (chapter 12 explains the mechanism).

Function expression

const greet = function (name) {
  return `Hi, ${name}`;
};
console.log(greet('Ravi'));   // → Hi, Ravi

The function is a value assigned to a variable — it exists only from that line onward, and you can pass it around like any data.

Arrow functions (ES6)

const square = (n) => n * n;                 // implicit return (expression body)
const sum = (a, b) => a + b;
const sayHi = () => console.log('hi');       // no parameters → keep ()
const double = (n) => {                      // block body needs explicit return
  return n * 2;
};

console.log(square(6));   // → 36
  • Single expression → return value is implicit (no return keyword).
  • Single parameter → parentheses optional (n => … works too).
  • No own this — they inherit it from the surrounding scope (critical for event handlers and methods; see The this Keyword).

Which form when?

FormUse it for
DeclarationNamed, reusable “tools” of the module (hoisting = flexible ordering)
Expression / const f = () => {}Assigning behaviour to a variable, callbacks, config objects
ArrowShort callbacks (map, filter), anywhere this should not rebound
Method in a class/objectRegular method() {} or this-aware arrows — see chapter 24

Parameters, arguments, defaults

function createUser(name, role = 'viewer', active = true) {
  return { name, role, active };
}

console.log(createUser('Mira'));
// → { name: 'Mira', role: 'viewer', active: true }
console.log(createUser('Kai', 'editor'));
// → { name: 'Kai', role: 'editor', active: true }

Defaults apply only when the argument is undefined (not when it is null or 0). Extra arguments are simply ignored; missing ones become undefined.

Rest parameters: accept any number of inputs

function total(...prices) {
  return prices.reduce((sum, p) => sum + p, 0);
}
console.log(total(10, 20, 5));   // → 35

...prices gathers remaining arguments into a real array (must be the last parameter).

Returning vs mutating

// Pure: same input → same output, no side effects (easy to test)
const addTax = (amount) => amount * 1.18;

// Impure: modifies outside state (use sparingly, name it honestly)
let log = [];
function track(event) { log.push(event); }

Prefer pure functions for logic; isolate impure ones at the edges (DOM, network, storage).

Functions as values (first-class citizens)

function twice(fn, value) {
  return fn(fn(value));
}
console.log(twice((n) => n + 3, 1));   // → 7

const shout = (s) => s.toUpperCase();
['hi', 'hey'].map(shout);               // → ['HI', 'HEY']

Passing functions into functions is the basis of callbacks, array methods, event handlers and every framework's API.

IIFE: run immediately

const result = (() => {
  const secret = 42;          // scoped to this function only
  return secret * 2;
})();
console.log(result);         // → 84; secret is not visible outside

An Immediately Invoked Function Expression creates a private scope in one shot — mostly needed in older scripts; ES modules (chapter 23) give real module scope instead.

Common mistakes

  • Forgetting return — the function yields undefined; a block-bodied arrow especially.
  • Side effects inside “getters” — functions that both compute and mutate are hard to test and debug.
  • Arrow functions as object/class methods — this will not be the object; see chapter 13 (The this Keyword).
  • Too many parameters — beyond ~3, accept one options object: createUser({ name, role }).
  • Naming functions like variables — verbs for actions: calculateTotal(), renderList(), booleans start with is/has.

Practice checklist

  1. Write celsiusToF(c) with an implicit-return arrow and verify with console.log.
  2. Create max(...nums) using rest parameters — handle the empty case too.
  3. Refactor a callback-heavy snippet into a named function and pass it by reference.
  4. Write a function that returns a function (a counter factory) and confirm each counter is independent.

Functions transform data — the most common data being lists. Next: Arrays & Array Methods.

Quiz: Functions in JavaScript

5 questions · 70% to pass

Frequently Asked Questions

JavaScript is the programming language of the web. It adds behaviour to pages: responding to clicks and input, validating forms, fetching data from APIs, updating the DOM without reloading, and much more. It also runs on servers (Node.js), in desktop and mobile apps, and in build tooling.

They are unrelated languages that share a similar name for historical marketing reasons. Java is a statically-typed compiled language; JavaScript is a dynamically-typed interpreted language designed for the browser. Knowing one does not imply knowledge of the other.

Helpful but not mandatory — HTML gives you the structure JavaScript manipulates and CSS the styling it toggles. If you know basic tags, classes and selectors, you have enough to start; the DOM chapters assume only that much.

Use const by default and let when the value must change. Avoid var entirely in modern code: it is function-scoped instead of block-scoped, hoists differently, and can create accidental globals. This course uses const and let throughout.

The Document Object Model is the browser’s in-memory tree of objects representing your HTML. JavaScript reads and modifies that tree — selecting elements, changing text, adding nodes, attaching event listeners — and the browser re-renders the page to match.

== compares after converting types (so 5 == "5" is true), while === requires the same value AND the same type (5 === "5" is false). Loose equality has famously confusing rules — use === and !== everywhere unless you have a specific reason not to.

JavaScript is single-threaded, so long-running work (timers, fetches, events) is handled by the browser and its callbacks are queued. The event loop moves queued callbacks onto the call stack only when it is empty, with promise callbacks (microtasks) taking priority over timers. It is why asynchronous code never freezes the page.

A Promise is an object representing a future value — pending, fulfilled or rejected — that can be chained and combined (Promise.all). async/await is syntax sugar over promises that lets asynchronous code read top-to-bottom with ordinary try/catch error handling.

Yes. Frameworks are built on exactly these fundamentals — components are functions, state is your variable discipline, effects are events, rendering is DOM work. Developers who learn vanilla first understand what the framework is doing and debug far faster.

Type out the examples instead of copying, build small end-to-end projects (expense tracker, weather app, quiz), handle every UI state (loading, empty, success, error), and revisit fundamentals while reading real code. Consistency beats volume — a little most days outpaces occasional marathons.