Arrow Functions

Functions in JavaScript are defined with a function statement like this, right?

function logUrl(tld) {
console.log(`http://example.${tld}`);
}

Sometimes they are. But there are other ways. For example, you can leave off the function's name. A function without a name is a function literal, just as 17 is an integer literal. To do something with the function, you have several choices. You could assign the function literal to a variable:

const logUrl = function(tld) {
console.log(`http://example.${tld}`);
};

logUrl('com');

This works because a function literal is an expression that has a value. The mechanic of assignment is no different than it is for assigning a string expression to a variable. The only difference is the type of values.

Assigning a function literal to a variable is mostly the same as just naming the function using a normal function statement. The difference is that a function statement has a wider scope than an assigned function literal. Function statements are hoisted to the top of the scope in which they are declared so that they can be called in code that appears before their definition. Function literals are not hoisted. They can only be called after they have been assigned.

Another option is to immediately call the function literal without ever giving it a name:

(function(tld) {
console.log(`http://example.${tld}`);
})('com');

This code might feel inscrutable. The function literal evaluates to a callable function. Placing parentheses after it calls the function. This form is sometimes called an immediately-invoked function expression (IIFE).

A third option is pass the function literal along as a parameter to some other function. Array.forEach, for example, expects a function as a parameter and applies it to each element in the array.

const tlds = ["com", "edu", "org", "gov"];
tlds.forEach(function(tld) {
console.log(`http://example.${tld}`);
});

As with an IIFE, a function passed as a parameter is never given a name in the calling scope.

You will encounter all three of these forms in the JavaScript code you run across. It is important to be able to recognize them. However, as you contine reading this book, you will frequently see a fourth form: an arrow function. An arrow function is a concise notation of an unnamed function that has this grammatical form:

(parameter1, parameter2, ...) => {
// function body
}

Note the complete lack of keywords. If there's only a single parameter, the parentheses may be omitted:

parameter => {
// function body
}

If the function body is a single statement, the curly braces may be omitted:

parameter => statement
// This is shorthand for:
// (parameter) => {
// statement;
// }

If the single statement is a return statement, even the return may be omitted, leaving just the bare expression:

parameter => expression
// This is shorthand for:
// (parameter) => {
// return expression;
// }

An advantage of arrow functions is that they reduce the noise of creating functions and passing them around as callbacks. You could assign them to a variable just like a function literal:

const logUrl = tld => console.log(`http://example.${tld}`);
logUrl('com');

But you will commonly see them passed directly as parameters:

const tlds = ["com", "edu", "org", "gov"];
tlds.forEach(tld => console.log(`http://example.${tld}`));

Try creating an array in your browser's console and using the array's find and findIndex methods to search for elements within that meet some criteria. Like forEach, both of these methods apply their parameter function to the elements of the array, one at a time. The parameter function must be a boolean predicate, returning true or false. If the predicate returns true, the method stops searching and returns its result. Pass arrow functions for the predicates.

What arrow function would you use to locate the index of the first negative value? What arrow function would you use to get the first element that was divisible by 5?

When JavaScript was standardized, it was formally given the name ECMAScript in a nod to Ecma International, the standards body that oversaw the standardization process. Arrow functions appeared in ECMAScript 6 (ES6), which was published in 2015. The other forms of functions have been around a lot longer, and that's why you still see them in others' code. Function statements, function literals, and arrow functions also have some other differences not discussed here that may influence which form a web developer uses.

You may pass arrow functions as callbacks to addEventListener or JavaScript's timer functions. Try converting this code to use an arrow function instead of a function name:

function roll() {
console.log(`You rolled a ${Math.floor(Math.random() * 6) + 1}.`);
}
setTimeout(roll, 1000);

For the exercises in this book, which form you use is a matter of taste and readability.