Functions

The word “function” has a variety of meanings in programming. For example, in the world of Functional Programming, “function” has a precise mathematical definition and implies a strict set of rules to abide by.

In JS, we should consider “function” to take the broader meaning of another related term: “procedure.” A procedure is a collection of statements that can be invoked one or more times, may be provided some inputs, and may give back one or more outputs.

From the early days of JS, function definition looked like:

  1. function awesomeFunction(coolThings) {
  2. // ..
  3. return amazingStuff;
  4. }

This is called a function declaration because it appears as a statement by itself, not as an expression in another statement. The association between the identifier awesomeFunction and the function value happens during the compile phase of the code, before that code is executed.

In contrast to a function declaration statement, a function expression can be defined and assigned like this:

  1. // let awesomeFunction = ..
  2. // const awesomeFunction = ..
  3. var awesomeFunction = function(coolThings) {
  4. // ..
  5. return amazingStuff;
  6. };

This function is an expression that is assigned to the variable awesomeFunction. Different from the function declaration form, a function expression is not associated with its identifier until that statement during runtime.

It’s extremely important to note that in JS, functions are values that can be assigned (as shown in this snippet) and passed around. In fact, JS functions are a special type of the object value type. Not all languages treat functions as values, but it’s essential for a language to support the functional programming pattern, as JS does.

JS functions can receive parameter input:

  1. function greeting(myName) {
  2. console.log(`Hello, ${ myName }!`);
  3. }
  4. greeting("Kyle"); // Hello, Kyle!

In this snippet, myName is called a parameter, which acts as a local variable inside the function. Functions can be defined to receive any number of parameters, from none upward, as you see fit. Each parameter is assigned the argument value that you pass in that position ("Kyle", here) of the call.

Functions also can return values using the return keyword:

  1. function greeting(myName) {
  2. return `Hello, ${ myName }!`;
  3. }
  4. var msg = greeting("Kyle");
  5. console.log(msg); // Hello, Kyle!

You can only return a single value, but if you have more values to return, you can wrap them up into a single object/array.

Since functions are values, they can be assigned as properties on objects:

  1. var whatToSay = {
  2. greeting() {
  3. console.log("Hello!");
  4. },
  5. question() {
  6. console.log("What's your name?");
  7. },
  8. answer() {
  9. console.log("My name is Kyle.");
  10. }
  11. };
  12. whatToSay.greeting();
  13. // Hello!

In this snippet, references to three functions (greeting(), question(), and answer()) are included in the object held by whatToSay. Each function can be called by accessing the property to retrieve the function reference value. Compare this straightforward style of defining functions on an object to the more sophisticated class syntax discussed later in this chapter.

There are many varied forms that functions take in JS. We dig into these variations in Appendix A, “So Many Function Forms.”