What you'll be able to do

By the end of this page you should be able to write a small named function, call it with arguments, use parameters inside the body, and return a value to the caller. You will also recognize the classic bug: the function “works” in your head, but the caller gets undefined because nothing was returned.

Previous post: break, continue, and loop control.

Who this is for

  • People who paste the same three lines in three places and dread changing one of them
  • Beginners who write a function, call it, and log undefined
  • Anyone who mixes up “parameter” (the name in the definition) and “argument” (the value you pass in)

You can skip this if you already declare functions, pass arguments, and always return when the caller needs a value. Come back when a helper “does something” but the next line never gets the result.

What a function is

A function is a named (or later, anonymous) block of instructions you can run whenever you call it. You write the recipe once; you run it many times.

function sayHello() {
  console.log("Hello");
}

sayHello();
sayHello();

Scenario A — a greeting button. Each click calls sayHello(). You do not rewrite the log line for every click.

Scenario B — setup you run twice. Page load and a “reset” button both call resetForm(). One definition, two call sites.

The parentheses () mean “run this now.” Writing sayHello without () only refers to the function value — it does not run the body. That matters later when you pass functions around; for today, call with ().

Parameters and arguments

Parameters are the names in the function definition. Arguments are the values you pass when you call.

function greet(name) {
  console.log("Hello, " + name);
}

greet("Asha");
greet("Ravi");

Here name is the parameter. "Asha" and "Ravi" are arguments.

Scenario A — one input. greet(userName) after a form trim. The function does not care where the string came from.

Scenario B — several inputs. Order matters:

function describeClip(title, seconds) {
  console.log(title + " (" + seconds + "s)");
}

describeClip("Intro", 12);

If you swap arguments — describeClip(12, "Intro") — you get a nonsense label. Match the order to the parameter list.

If you pass fewer arguments than parameters, the missing ones are undefined inside the function. Later posts cover defaults; for now, pass what you mean or check before use.

return: send a value back

console.log shows something; return hands a value to the caller so they can store it or use it.

function double(n) {
  return n * 2;
}

const result = double(5);
console.log(result);

That logs 10. double(5) is the number 10 wherever you use that call.

Scenario A — math helper. const total = price + tax(price) only works if tax returns a number.

Scenario B — forgot return.

function doubleBroken(n) {
  n * 2; // calculated, then thrown away
}

console.log(doubleBroken(5));

That logs undefined. The multiplication ran; nothing was sent back. This is the #1 beginner function bug.

Once return runs, the function stops. Lines after return in that path do not run:

function firstName(full) {
  if (!full) {
    return "";
  }
  return full.split(" ")[0];
}

Scenario A — early return for bad input. Empty in → empty string out, no crash on split.

Scenario B — happy path. Valid string → first word returned.

Functions that only do work (side effects)

Some functions return nothing useful on purpose. They change the page, log, or save — that is a side effect.

function showMessage(text) {
  const out = document.getElementById("out");
  out.textContent = text;
}

Scenario A — UI update. The caller does not need a return value; the screen changed.

Scenario B — mixing both. Prefer either “return data” or “update the DOM,” not both in a confusing way. If you update the DOM and return a value, document it so the next reader knows.

A function with no return still returns undefined. That is normal for side-effect helpers.

A tiny practice file

Save as functions.html. Type a number, click, and see double — or an error if the input is not a number.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Functions</title>
  </head>
  <body>
    <input id="raw" placeholder="Type a number" />
    <button id="go">Double it</button>
    <p id="out">Result will show here.</p>
    <script>
      function double(n) {
        return n * 2;
      }

      function show(text) {
        document.getElementById("out").textContent = text;
      }

      document.getElementById("go").addEventListener("click", function () {
        const n = Number(document.getElementById("raw").value.trim());
        if (Number.isNaN(n)) {
          show("Type a real number first.");
          return;
        }
        show("Double is " + double(n));
      });
    </script>
  </body>
</html>

Try removing return from double and click again — the message will look wrong because double(n) becomes undefined. Put return back.

Mistakes I see a lot

1. Forgetting return. Caller gets undefined. Log the call result to confirm.

2. Calling without (). greet vs greet() — one is the function, one runs it.

3. Using the parameter name outside the function. name only exists inside greet unless you declared it elsewhere.

4. Assuming console.log is a return. Logging helps you see; it does not give the caller a value.

5. Wrong argument order. Swap title and seconds and the bug looks like “formatting,” not “call site.”

6. Huge functions that do five jobs. Start small. One clear job per function is easier to test and name.

What to try before the next post

  1. Write add(a, b) that returns the sum; log add(2, 3).
  2. Call a function that only console.logs and assign the call to a variable — see undefined.
  3. Add an early return "" when an input string is empty.
  4. Build the tiny HTML file and break return on purpose once.

Next in this series: function declarations vs expressions — two shapes for the same idea, and what “hoisting” honestly means for beginners.

Try this next outside the series

Functions matter more once they stop being textbook examples and start shaping reusable app code.

  • Node.js async patterns — see functions return promises, accept callbacks, and coordinate real work
  • Diff Checker — compare two function versions before you keep a refactor