As I always have a little trouble remembering everything and also because there is a little collection side that I like, here is a summary of the different ways that exist to define functions in JavaScript.
Through a declaration
The classic method dates back to the origins of JavaScript and simply consists of declaring the function with the keyword function
.
function hello (firstname) {
console.log(`Hello ${firstname}`);
}
This function has the name "hello", which makes it a named function.
Through an expression
A more modern method that highlights the fact that functions are objects like any other and can also be assigned to variables.
const hello = function (firstname) {
console.log(`Hello ${firstname}`);
};
Even if this is not obvious, this function is anonymous:
- It is created without giving it a name (just "function (...) { ... }")
- Although it is assigned to a variable that has a name
Note: Since this is an assignment to a variable (in this case it's a function that is assigned), the command ends with a semicolon, exactly as is the case for all other assignments: const pi = 3.14;
.
Through the arrow syntax
With ES6 came the new syntax "arrow" to declare functions via an expression:
- Remove the keyword
function
before the list of arguments. - Add the symbol
=>
after this list.
const hello = (firstname) => {
console.log(`Hello ${firstname}`);
};
It's more compact and the goal is to get a cleaner code. This is why arrows functions can be further simplified:
- Only one parameter => no need to put it in parentheses.
- Only one line of code in the function => no need for a block "{ ... }".
- If the function only makes a "return..." => the keyword
return
is useless.
In the end, the following three declarations are identical:
const hello1 = function (firstname) {
return `Hello ${firstname}`;
};
const hello2 = (firstname) => {
return `Hello ${firstname}`;
};
const hello3 = firstname => `Hello ${firstname}`; // (°~°)
This clean aspect is really useful for callbacks. For example, with the .map()
method of tables that expects a callback function, you can get some interesting stuffs:
const test = [1, 2, 3];
function doubler (x) {
return x * 2;
}
test.map(doubler); // [2, 4, 6]
test.map(function (x) { return x * 2; }); // [2, 4, 6]
test.map((x) => { return x * 2; }); // [2, 4, 6]
test.map(x => x * 2); // [2, 4, 6] Bingo!
This post was originally published on my blog.
Cover image : Wall decorations with colorful butterflies - __ drz __.
Top comments (6)
I'm not a fan of declaring top-level functions as arrow functions:
I much prefer the good old fashioned function declaration:
Fewer characters isn't always better, I feel the second one is more readable.
I totally agree. That's why I add the (°~°) comment on the hello3 version.
But I hope this post will help me to integrate the new syntaxes.
Oops, I missed that 😂
Do not forget to mention their differences
like how the standard function declaration enables the function to be called anywhere within the scope even before it is declared
(Ex: declare all of your function at the bottom of the file)
Or how the arrow function has a different definition of
this
(For arrow functions it never changes even if the function is assigned to a different object)
Of course! But I wanted to keep it simple and limit myself to the syntax. It was better to avoid any reference to "this"...
I was about to suggest unholy magic by using goto.
I then realized ECMAScript does not have the curse of goto...
Sometimes it's the little things that make me happy.