DYK? Named vs Anonymous Functions
Over the years (almost a decade now!) I’ve been seeing how different developers write code for different applications. A lot of times, developers exchange creating functions with arrow functions or regular functions.
Difference by hoisting
One of the most focused topic about the differences between these two is hoisting, where named functions are hoisted (can be used before they are declared) and arrow functions are not.
sum(1, 2); // This works!
function sum(a, b) {
return a + b;
}
divide(2, 1); // ReferenceError: Cannot access 'divide' before initialization
const divide = (a, b) => a / b;
Take into account that for the above example, the arrow function can be translated as:
const divide = function (a, b) {
return a / b;
};
Sidenote: I’ve been seeing over the last weeks that it is weird that we got used to understand that this means something:
(() => {})();
But it’s easier when you translate it to a regular function:
function () {
return {};
}();
And the last () is just a function call! (known as an Immediately Invoked Function Expression, IIFE)
Arrow functions are named!
I’ve heard before that arrow functions are also known as “anonymous functions”. Why? It’s because arrow functions don’t have an explicit name in their syntax. However, when you assign them to a variable, JavaScript automatically infers the name from that variable.
So, although people sometimes call arrow functions “anonymous,” they’re only truly anonymous if they’re not assigned to any variable or property. In practice, most arrow functions in real-world code end up being named by inference.
Following the previous example:
const divide = (a, b) => a / b;
// Is the same as
const divide = function (a, b) {
return a / b;
};
As you can see here, the function keyword has no name. But there is a catch!
They do have a name, given by inference. If you do:
console.log(divide.name); // "divide"
You will see that the name of the function is “divide”! This is due to function name inference introduced in ES6.
What about anonymous functions?
Yes, it is possible to create functions without a name. But it’s very unusual to create a function (but useful sometimes) or even a component with as anonymous
export default function () {
return (
<div>
<h1>Hello, world!</h1>
</div>
);
}
Although this is a valid React component (you could import it as a named export or default export), it’s a common practice to have some name for the component.
Also, did you know that named functions are easier to debug? If your app crashes due to an error, if you use a named function, you will see the name of the function in the stack trace.
For instance, if we are developing a React Component where we have a function that is not working as expected:
function MyComponent() {
throw new Error('This is an error');
}
MyComponent();
we could see the name of the function in the stack trace:
Error: This is an error
at MyComponent
at renderWithHooks
at mountIndeterminateComponent
Even if we use an anonymous function assigned to a variable, modern JavaScript engines will infer the name:
const MyComponent = () => {
throw new Error('This is an error');
};
MyComponent();
Error: This is an error
at MyComponent
at renderWithHooks
at mountIndeterminateComponent
But if we use an anonymous function, it will not show up in the stack trace:
export default function () {
throw new Error('This is an error');
};
MyComponent();
Error: This is an error
at <anonymous>
at renderWithHooks
at mountIndeterminateComponent