Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

JavaScript Functions

Learn JavaScript's three function syntaxes, parameters and returns, default and rest parameters, arrow functions, and the scope rules behind them.

Levels: Beginner ~16 min read

Basic

Functions are JavaScript's unit of reuse and its most load-bearing idea; the language has been shaped around them for thirty years. You will meet three syntaxes in the first hour of any real codebase, declarations, function expressions, and arrows, and all three do the same fundamental job: accept inputs, run, return a value. The differences are conveniences and one deep behavioral trap, and knowing which syntax is which is the difference between reading modern code and decoding it.

The three syntaxes

javascript syntaxes.js
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// declaration: hoisted, named, callable before its line
function priceWithTax(amount, rate) {
  return amount * (1 + rate);
}

// expression: a value stored in a variable
const priceWithTax = function (amount, rate) {
  return amount * (1 + rate);
};

// arrow: compact, expression bodies return themselves
const priceWithTax = (amount, rate) => amount * (1 + rate);

Three spellings of one idea; teams default to the arrow.

Declarations are hoisted, usable above the line where they are written, which makes them the choice for top-level building blocks. Expressions and arrows exist only after their line executes, and arrows shine as short arguments: the one-expression body returns its value with no return keyword, and a single parameter needs no parentheses. The one deep difference, arrows not binding their own this, matters once you meet objects and classes, and deserves a flag in your memory rather than a worry right now.

Parameters: defaults and rest

Parameters fill left to right, missing ones arrive as undefined, and defaults are written inline with =. Any parameter may be defaulted, and later parameters can use earlier ones, which handles the compute-it-if-missing pattern cleanly. For a varying number of arguments, the rest parameter ... gathers everything remaining into a real array.

javascript parameters.js
1
2
3
4
5
6
7
8
9
function receipt(bread, count = 1, rate = 0.14, ...extras) {
  const total = count * 45.5 * (1 + rate);
  return `${count} x ${bread}: ${total.toFixed(2)}`;
}

receipt("rye");                    // 1 loaf, default rate
receipt("buns", 6);                // 6 buns
receipt("buns", 6, 0.05, "wrap", "slice");
// extras is ["wrap", "slice"]

Defaults, chaining, and the rest, in one signature.

Returns, and the default one

return ends the function and hands back a value; execution stops at the first one reached. A function that finishes without meeting a return returns undefined quietly, the JavaScript echo of Python's None, and the reason a forgotten return shows up as undefined in output rather than as an error. Arrow functions with block bodies, braces, need return like any other function; only the brace-less expression form returns implicitly.

Scope: what a function can see

Names declared inside a function are local to it, and const and let stay in the block that declares them, the loop body included, while var leaks to the whole function and is a legacy spelling worth recognizing and not writing. Modern code declares with const by default and let only when rebinding is genuinely needed, a habit that prevents a whole family of accidental-overwrite bugs before they exist.

Compose a small receipt engine

The example below builds the bakery arithmetic from three arrow functions and prints receipts to the preview console. Run it, then exercise the design: change the tax rate in one place and watch every receipt follow, which is the entire argument for functions. Add a discount = 0 parameter to lineTotal and pass it by name from one call only. Then delete the return from lineTotal to meet the quiet undefined that shows up inside every receipt.

Interactive Runnable example
Edit

Ready to run.

What to notice

  • One defaulted rate changed every receipt, because the knowledge lives in one signature.

  • Composition read as a sentence: a receipt line is tax applied to a line total.

  • The brace-less shout arrow returned without the keyword; the braced receipt function needed it.


Quick check

If you can explain what a missing return hands back, when an arrow needs braces and a return keyword, and why const is the default spelling, functions are yours in all three syntaxes. Next, arrays, and the methods that eat loops. When you are ready, take the JavaScript Functions quiz.

Was this page helpful?

Mark this learning resource complete to track your learning progress.