Course outline · 0% complete

0/29 lessons0%

Course overview →

Function expressions and arrow functions

lesson 6-2 · ~9 min · 19/29

Functions are values

This idea matters because half of JavaScript's standard library takes a function as input. The array methods in unit 7 ask what to do with each item, timers ask what to run later, and servers ask what to do per request. Handing code around like that only works if a function is a value you can store and pass.

In JavaScript a function is a value in the same sense that 42 and "hi" are, so it can be stored in a variable:

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

That is a function expression. Since 2015 there is a shorter spelling you will see everywhere, the arrow function:

const double = n => n * 2;

The arrow forms differ only in how much syntax the situation needs:

FormMeaning
n => n * 2one parameter, body is one expression, returned automatically
(a, b) => a + btwo or more parameters need parentheses
() => "hi"no parameters, empty parentheses
n => { const d = n * 2; return d; }braces make a full body, so return is required

Python's lambda n: n * 2 is the closest cousin, though arrows are not restricted to a single expression the way lambdas are. Arrows matter enormously in unit 7, where you hand them to array methods by the dozen.

Three functions stored in variables

The same idea written three ways: a function expression, a one-parameter arrow, and a two-parameter arrow. All three end up in a const and are called with ordinary parentheses.

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

const triple = n => n * 3;
const add = (a, b) => a + b;

console.log(double(4));
console.log(triple(4));
console.log(add(2, 3));

Output

8
12
5

double and triple do the same kind of work with very different amounts of syntax. The function expression needs the function keyword, braces, and an explicit return, while the arrow needs none of them because a body with no braces is returned automatically. Written as an arrow, double would be const double = n => n * 2;.

add shows the one rule that trips people up: parentheses around the parameters become mandatory as soon as there are two of them.

Two arrows returning a number and a boolean

square returns a number and isEven returns a boolean, and both fit on one line because each body is a single expression.

const square = n => n * n;
const isEven = n => n % 2 === 0;

console.log(square(6));
console.log(isEven(7));

Output

36
false

isEven combines two operators from earlier lessons: % from lesson 1-2 to get the remainder, and === from lesson 2-3 to compare it against zero. An even number divided by 2 leaves nothing over, which is what n % 2 === 0 checks, and 7 leaves 1, so the result is false.

The expression n % 2 === 0 is already a boolean, so wrapping it in an if that returns true or false would only add noise. Returning a comparison directly is the idiomatic way to write a predicate, and unit 7 passes functions of exactly this shape to filter.

Writing an arrow that adds one

The correct arrow is const inc = n => n + 1;, where the expression after => becomes the return value with no return keyword needed.

The near miss is worth studying, because it is one of the most common arrow bugs. Writing n => { n + 1 } adds braces, and braces create a full function body rather than a returned expression. That body computes n + 1, throws the result away, and returns undefined, all without any error to warn you. Adding the keyword back, as n => { return n + 1; }, makes it correct again.

Two spellings to keep straight: the arrow is always => and never ->, and braces after an arrow always demand an explicit return.