Functions

In this article, we're going to explore functions in JavaScript, how to create and use one.

So, what is a JavaScript function? A function is a group of instructions that together perform a task; it is defined once and can be used (i.e. called) as many times as needed.

Declaring a function

A function is declared via the `function` keyword:

function sayHello(name) {
  return "Hello " + name;
}

Using a function

Here is how to call our `sayHello` function, using "Paul" as value for the `name` parameter:

sayHello("Paul");
"Hello Paul"

Returned value

A function always returns a value; if nothing is specified, `undefined` is returned. In the example below, we're printing "Hello Paul" to the console but not return a value. The second `console.log` will show `undefined` as the result of calling `sayHello("Paul")`

function sayHello(name) {
  console.log("Hello " + name);
}
console.log(sayHello("Paul"));
undefined

Default arguments

Let's see what happens if we "forget" to send an argument to the function:

function sayHello(name) {
  return "Hello " + name;
}
console.log(sayHello());
"Hello undefined"

Notice that `undefined` is appended to the "Hello " string before being returned.

We can, however, specify a default value to be used for a parameter:

function sayHello(name = "World") {
  return "Hello " + name;
}
console.log(sayHello());
"Hello World"

Anonymous functions

A typical JavaScript function has a name and parameters:

function sayHello(name) {
  return "Hello " + name;
}

Declaring an anonymous function

Just as the name implies, an anonymous JavaScript function is a function without a name. The simplest example is assigning a function to a variable:

let sayHello = function(name) {
  return "Hello " + name;
}

Whilst the function doesn't have a name, because we've assigned it to a variable, we can use still call it when required:

console.log(sayHello("Paul"));
"Hello Paul"

Functions as parameters

A very common usecase for anonymous functions are as arguments for JavaScript functions, for example `setTimeout`:

setTimeout(function sayHello() {
  console.log("Hello World");
}, 1000);

`setTimeout` takes 2 arguments: a function to execute, and an interval in miliseconds after which the function is executed. In the example above, we've passed a function named `sayHello`, but, even though we've given it a name, the function won't be available to use:

sayHello();
ReferenceError: sayHello is not defined

Arrow Functions

In a previous article, we've looked at how to use JavaScript anonymous functions - they are nameless functions that are used extensively in methods that take function parameters:

let myArray = [1, 4, 42, 11, 79];
let doubleArray = myArray.map(function (item) {
  return item * 2;
});
console.log(doubleArray);
 [2, 8, 84, 22, 158]

ES6 introduced a new syntax for functions - our example can be written more concise as:

let myArray = [1, 4, 42, 11, 79];
let doubleArray = myArray.map( item => {
  return item * 2;
});
console.log(doubleArray);
[2, 8, 84, 22, 158]

DOM elements management

An area that benefited massively from this new syntax was DOM elements manipulation and actions. For example, triggering actions when a button is clicked is now as simple as:

let signupButton = document.getElementById("signup");
signupButton.click(event => {
  console.log(`New signup: ${signupButton}`);
});

`arguments` object

A special `arguments` object holds a list of all arguments passed to a JavaScript function even if none are specified in its definition.

A function is usually defined via the `function` keyword with arguments, if required, specified in following parenthesis. In the example below we've defined a `sayHello` function with 2 parameters:

function sayHello(name, business) {
  console.log(`Hello ${name} from ${business}!`);
}
sayHello("Paul", "90-10.dev");
"Hello Paul from 90-10.dev!"

Inside the function, parameters are accessed via their names given in the function definition, `name` & `business` in our case.

However, there is another way to access any data passed onto the function, via the special `arguments` object where any passed on data is stored:

function sayHello() {
  console.log(arguments);
}
sayHello("Paul", "90-10.dev");

The console will show:

Arguments { 0: "Paul", 1: "90-10.dev", … }

And we can check if indeed `arguments` is an object:

console.log(typeof arguments);
object

... and we can check how many were passed and even list all arguments:

function sayHello() {
  console.log(arguments.length);
  for(let arg of arguments) {
    console.log(arg);
  }
}

Using `arguments`

Arguments can be accessed in an array-like fashion using indices:

function sayHello() {
  console.log(`Hello ${arguments[0]} from ${arguments[1]}!`);
}
sayHello("Paul", "90-10.dev");
"Hello Paul from 90-10.dev!"

Modifying `arguments`

Arguments can also be modified on the fly:

function sayHello() {
  arguments[0] = "World";
  console.log(`Hello ${arguments[0]} from ${arguments[1]}!`);
}
sayHello("Paul", "90-10.dev");
"Hello World from 90-10.dev!"

Reading List