When it comes to writing a function, which style do you prefer?
const
const doSomethingCool: string = () => 'yes'
OR
function
function doSomethingCool(): string {
return 'yes';
}
My Thoughts
Personally, after years of using const, I have recently switched back over to function for a few reasons.
- The intent is clear and concise, so that readers quickly differentiate between variables and functions. The faster you know what is going on, the better right?
- Function hoisting, meaning it lets you use a function before you declare it in your code, where with const it will be
undefined
until it has been reached in the execution.- Also hoisting issues related to using function in bundling tools is no longer the issue it once was
- Named functions show up in stack trace messages, which is handy
Edge-cases
While I have switched to using function in most cases, arrow functions still serve a important purpose in my codebase. Such as providing callbacks to high order functions, such as map
, reduce
, forEach
, etc...
function iStillLikeArrows(users: Array<User>): Array<string> {
return users.map(u => u.name);
}
What Are Your Thoughts?
I would love to hear other opinions on this topic, and see different reasons/viewpoints as to why to favor one side more than the other.
Also remember, no one is wrong choosing one or the other, it's a personal preference.
Top comments (19)
There are technical differences that should be considered over personal preferences:
this
and can't be used as a constructor while function can be.Note you can also do:
Which both prevents reassignment and creates a lexical context.
So it's a matter of needs on a given point on your software.
Thank you for this comment. It's not obvious for some JS developers...
Anytime 😄
In React, I tend to use
function
for components andconst
for likeonSubmit
handlers within those components. Just feels better to me for some reason :)100% agree. Declaring your functions as functions is much easier to understand than having to read the whole line, to see if you're assinging an arrow function to that const. Arrow functions are great as a replacement for annonymous functions in callbacks.
I think there's no need to read the whole line to know whether some const is a function or not.
Read the comment I let above where I explain the technical insights on that so you can choose const or function whenever suits best 😊
None of them should be. alotofcharacters is a subject so I'd expect to return just that (a lot of characters) after the evaluation.
Using a bad naming style/convention and blame a language feature is weird dude.
facepalm alotofcharacters is not the name of the function... I should have replaced it with Chinese characters... How fast can you interpret Chinese?
While I agree that using the keyword
function
is more suitable to indicate the intention, I think @joelbonetr's point is also valid that following good naming convention serves the same purpose. Even if your function name is too long you don't need to read the name to the end to tell whether it's a function, if the name starts with a verb:I prefer to use function instead of const, just because of it is directly referring to the function. and yes, it is much easy to read!
A few observations:
I'm thinking of going back to the
function
statement, in react especially. Mostly because you can doexport default function MyFunction
but have to put the default export on another line with theconst
style of function declarations.I tend to use the former (const) method, but I do think it can get out of hand, especially with typescript, and especially with the frankly terrible conventions for piling parentheses and braces and brackets and bears all together that Javascript developers tend to enjoy.
You end up with a 200-character line for a function definition, or split it over several at inconsistent points, where with the old-school method, everything's way more readable.
I've written a bunch of code in the last 30 years in a bunch of languages. I was there when JavaScript was launched, and I understand as a slot-based language there's fundamentally no real distinction between "data slots" and "executable slots".
So I get why the
const x: thing = () => {…}
pattern exists, as part of that legacy.The last time I was as confused by syntax was C++ templates which I never really understood. Typed arrow functions with templates are borderline impenetrably difficult IMHO. Check this (real world) function one of my team members wrote using using arrow syntax:
export const useSearchPhraseResolver: () => (searchPhrase: string) => Promise<SearchResultItem[]> = () => {}
vs the function syntax:
export function useSearchPhraseResolver(): (searchPhrase: string) => Promise<SearchResultItem[]> {}
(sorry I'd have put indenting etc but dev.to doesn't seem to have even the most rudimentary way to show code that I can figure out… )
You tell me which is easier to understand (and therefore which is less likely to introduce errors :) )
I highly doubt unless you're using something like web workers or node cluster either method will ever show a difference from the other. That being said, a declared function shows up differently in the AST.
const
, no hoisting = no guessing = predictable