Took a quick 10m google to find a debate on this idea, but wasn't able to find anything.
So really, which is more readable to you:
This? (named function)
function foo (bar) {
//some code
}
Or this? (function as a variable)
const foo = bar => {
//some code
}
Keep in mind having other variables in the same scope along with these functions and trying to debug it!
Personally, where I currently work, we keep a strict concern about the main script functions (ones not inside of a scope) to be what I called named functions
. I've been with the team for ~6 months, and we've had people who originally argue for functions as variables change their stance to that named functions are more readable.
What's your stance?
Top comments (10)
I prefer named functions,
because I can immediately see that it's a function.
I see some advantages to both, not just in terms of readability (which, as you've said, is the most important thing), but functionality.
With named-function syntax, the function becomes available at parse time. You can define it at the end of a scope and it will be available at the beginning of the scope. I sometimes prefer to put helper functions at the end of a scope, so that rules out function-as-variable syntax.
With function-as-var syntax, you can use the ❤️
const
❤️ keyword, which prevents it from being accidentally redefined later. It also lets you take advantage of the ES6 arrow function's inheritedthis
behavior, which is good if that's what you want, or bad if you want tobind
the function manually.Also, don't forget the third option, ES6 method syntax:
It's only available inside of object and class definitions, but I really like it.
I haven't committed entirely to any one of these syntaxes. I use whichever one seems to fit what I'm doing and makes my code easy to understand.
Named functions are more recognizable and readable in stack traces. When you're debugging, that can make a large difference in how many hairs you pull out (or have left at the end).
Arrow notation to me is more useful when the function is "really functional": without side-effect, without impact on internal or external data, and repeatable. I see it more for "spontaneous" functions being passed to high order functions.
I also prefer named functions for most uses!
Do they also inherit the
this
scope? I've always used functions as variables when I've wanted to keep the scope ofthis
constant among nested functions.I use both of them depending of the use case.
I tend to prefer the function as a variable with arrow syntax 'cause it make the current context unreachable (binding to the parent context instead). It enforce future developers to write pure functions instead of relying on
this
.For plain JS I typically prefer named functions for readability, but if using TypeScript I often notice that certain types of functions arise often - when a function itself can be considered a domain object (i.e. it has a specific call signature that is meaningful in the problem space), I usually use a function variable because that allows me to use a descriptive type that provides better context than just "function." For example, in a redux application you might have a type for a reducer:
Then, you can use the type to describe your reducer function:
Definitely more verbose, perhaps even less readable. But to me, it's worth it for the added type safety (YMMV)
I think the hidden gem here is that your team enforces consistent style rules. What's "readable" is often more dependent on what you're used to seeing than on any particular syntax. (See: Scheme, Perl.) Kudos to your team leadership for establishing and maintaining that.
They are used differently as they behave differently. This depends if you want your function hoisted.
named functions!
I like functions as variables specially when I'm working with jQuery.
You can have some very clear syntax like:
zipcode_field.on('change', calculateShippingFee);