I was going through some JavaScript code with my mentee and he pointed to two functions and asked why they were declared differently.
I was quickly taken back to when I entered the JavaScript world from Java. I think it was around the time when the use of ECMAScript 6 (ES6) was picking up steam and things became even more confusing to me. “Who are the Ecma group again? And why and how do they standardize the language” - Those were some of the questions that were running through my head when I was getting through the quirks and syntax of JavaScript. But yeah, we were talking about functions. It is possible that you have written them in both ways, and do not immediately realize that you have a personal preference for one over the other or even realize their differences
The two main ways of writing function are can be generally categorized into Function declarations and Function exclamations.
These are declared like so:
function doSomething() {
console.log("Hello World");
}As you can see, it is not assigned to any variable. Hence, it is hoisted and put into memory so that it is ready for use immediately. Like so:
doSomething();
function doSomething() {
console.log("Hello World");
}In the above, I called doSomething() even before it was declared and it still works!
Typical Function expressions unlike their declaration comrade, are stored in a variable and then used as a function.
const x = function () {
console.log("Hello World");
}
x();Unlike the function declaration, doing the code below will result in an error:
x(); // TypeError: x is not a function
const x = function () {
console.log("Hello World");
}Function expressions can manifest themselves in different ways. The above example is an anonymous function because it is not named (for example doSomething ). We just simply assigned the function to the variable x.
We could also use the compact ES6 arrow function.
const x = () => {
console.log("Hello World")
}The above comes in handy when you want to escape this binding (they do not have their own this ) or simply use it as a callback in another function, like in the array map function below:
const x = function(currentValue) {
// do stuff with currentValue
}
myArray.map(x)or even more elegantly…
myArray.map(currentValue => {
// do stuff with currentValue
})Oh, then there’s the IIFE (Immediately Invoked Function Expression) - which does exactly what the name implies. It runs as soon as it’s created.
(() => {
//do stuff here
}) ()Notice how there is no name? It’s never going to be referenced so why name it.
To conclude, using one over the other lies in when and where the function is needed. Is it one that could be invoked anywhere at any time or can we avoid polluting the global scope?
Hopefully, you gained something from this post. Whether it was learning about hoisting or knowing the names of the different ways of declaring functions, or simply just a refresher on one of the foundations of the language