In this lesson, we'll explain another method of defining a function called function expressions. We'll be using function expressions in the next lesson when we learn about event handling with event handler properties.
First, let's start with a review.
It's optional to code along with this lesson. If you want to code along, review how to format code in the DevTools Console:
shift
+ enter
.tab
. To configure the console to use 2 spaces for indentation with tab
, in the DevTools window, go to Settings > Preferences > scroll to the Sources section > set "Default indentation" to 2 spaces.What do we know so far about functions?
parseInt()
, but mostly we will be writing our own custom functions. This is in contrast to methods: we will only be using built-in JavaScript methods until we revisit objects in the Object-Oriented JavaScript course section.Here's a function called duplicate()
that we've defined using a function declaration:
function duplicate(phrase) {
return phrase.concat(" ").concat(phrase);
}
When we write a function like this, it's called a function declaration. This means we've defined a function starting with the function
keyword. Here's the breakdown:
function
keyword indicates that we are declaring a function.duplicate
is the name of the function, and we always include parentheses ()
after the function name. The parentheses are to hold optional parameters.phrase
is a parameter: a placeholder for any values that we want to pass into the function when we call it. In this example, the data type of phrase
should be a string.{
and }
is called the function body; this is where we write out all the code that we want the function to execute when we call it.When we call this function, we need to pass an argument in. An argument is the value that is passed into a parameter. The function call will look like this:
> duplicate("echo");
"echo echo"
Function declarations are also called function statements, though that is less common.
We can also define a function with a function expression. This involves storing a function inside a variable like this:
// this is a function expression
const add = function(number1, number2) {
return number1 + number2;
};
This style of declaring a function is also called a function literal, though this term is less commonly used.
You might be wondering why we added a semicolon to the end of the function expression. Doesn't the curly brace indicate the end of the function? Yes, it does, but we are treating this similarly to other statements where we assign a value to a variable. For that reason, we are adding a semicolon to the end.
We can then call this function by doing the following:
> add(3, 5)
8
As we can see, calling the function works in exactly the same way as it does when we write the function as a function declaration:
// this is a function declaration
function add(number1, number2) {
return number1 + number2;
}
The main difference between a function expression and a function declaration is the function name, which can be omitted in function expressions to create anonymous functions. The example we've seen so far has been an anonymous function expression. Even though we're storing the function into a variable add
, and we can call the function by adding parens at the end of the variable name add()
, the function expression is still considered anonymous.
To write a named function expression, it would look like this:
// this is a **named** function expression
const calc = function add(number1, number2) {
return number1 + number2;
};
Notice that we've re-written the original add()
function expression. Now, we've given the name add
to our function expression (function add() {...}
), and we're storing it in a variable called calc
. If we wanted to call this named function expression, we would do so like this:
> calc(2,3);
5
The use cases for named function expressions are limited and you likely won't use them in the program. You are welcome to explore more about these use cases by referencing this section on MDN.
Another important difference between these two methods of defining a function have to do with hoisting. JS interpreters (programs that interpret JS code, like Google Chrome's V8 JavaScript engine) perform hoisting, which is the process of moving the declaration of functions and variables to the top of their scope, prior to execution of the code. Let's understand this with an example. Copy and paste this code into your DevTools console
const result = add(3, 5);
function add(number1, number2) {
return number1 + number2;
}
result;
Take note that we've called the add()
function before we've declared it, and declared our add()
function with a function declaration. Will this code execute properly?
When we hit 'enter' the code executes without error and we get 8
as the result. In this case we can call add()
before it has been defined because of hoisting. This only happens with function declarations.
Now refresh your page and your DevTools console and copy/paste this code and hit enter:
const result = add(3, 5);
const add = function(number1, number2) {
return number1 + number2;
}
result;
And what do we get? An error, specifically this one:
Uncaught ReferenceError: add is not defined
The difference with the second code snippet is that we've defined our add()
function with a function expression, which does not get hoisted. Code gets read from top to bottom, and in this case when we call add(3,5)
, our browser's JS interpreter can't find this function because it hasn't been hoisted and literally doesn't exist yet.
Generally speaking you should stick to using function declarations because that code gets hoisted. However, you'll see a lot of examples online that use function expressions, so it's very important for you to be able to recognize and use them.
In this course section, we'll learn how to use function expressions in the context of event handling. We'll get started on this in the next lesson!
Later on, we'll also learn how to use function declarations in event handling. When we get there, we'll cover the differences between the two and when we would choose to use one over the other.
There are more ways to define a function than just function declarations and function expressions. If you want to learn more, check out MDN's reference page on functions:
There's quite a lot on that reference page, including more information and examples about function declarations and expressions. If you find the additional information on MDN confusing or overwhelming, that's entirely normal when you are first starting out. Take note that everything that you'll need to be successful in terms of writing functions can be found in this section's content, so there's no immediate need to reference MDN.
You should generally default to using function declarations.
// this is a function declaration
function add(number1, number2) {
return number1 + number2;
}
We'll use these in event handling.
// this is a function expression
const add = function(number1, number2) {
return number1 + number2;
};
We won't use these in the program.
// this is a **named** function expression
const calc = function add(number1, number2) {
return number1 + number2;
};