Prefer function declarations

— 4 minute read

I've noticed for the last few years that developers tend to overuse arrow functions. It feels at times that people do it out of hype, or they avoid function declarations as we all avoid var now. There is nothing wrong with arrow functions. But they should not be used everywhere because it is possible to use them in most cases.

For me, and for many other people, arrow functions are harder to read. Because it's not a single English word, it's a combination of symbols usually not placed together. And it breaks natural reading flow from left to right in English. It requires the brain to parse more to understand what is in front of use.

Comparing a function and an arrow function permalink

Let's compare an arrow function and a function declaration:

function toggleContext() {}

let toggleContext = () => {};

How the first one reads: function toggleContext. Done! Two words.

How the second one reads: variable toggleContext is... eh... an arrow function. So toggleContext is a function. Done.

Function declaration reads much faster. It's two words, no need to go back and forth searching for an arrow => and for the name.

Perhaps comparing arrow function expression would be more correct with a function expression. Let's see them in the next example.

While there are no parameters in a function, scanning for an arrow could be a relatively fast brain operation. Having parameters makes things even worse for an arrow function:

let rule = function(result, ruleName, ...optionDescriptions) {};

let rule = (result, ruleName, ...optionDescriptions) => {};

Because we read from left to right in English, function keyword is the first thing we see in a function expression. We don't need to read and skip all parameters to find => to realize we're having a function here.

Arrow functions could be nice for callbacks, though. Because for callback we already expect a function to be there, so we don't need to guess if it's function or something else:

array.forEach((item) => {})

let something = Promise.resolve().then(() => {});

React function components permalink

Nowadays almost every React component it's a function component. And I see many developers declare them as arrow function expressions:

let Block = (props) => {
return <span>{props.children}</span>;

Isn't it nicer to declare function components as a function? :) Very semantic!

function Block(props) {
return <span>{props.children}</span>;

Conclusion permalink

I think most people wouldn't care much what to use, they will choose whatever feels/looks nice. While for some people it's a matter of code readability or even accessibility of a code.

Personally I would order function syntax in the following order, from the most readable to the least readable:

  1. Function declaration (function hi() {}).
  2. Function expression (let hi = function() {}).
  3. Arrow function expression (let hi = () => {}).

There is nothing wrong with any of these functions. You can use whatever you want. But be aware that some choices would hurt readability for people, who read your code.