DEV Community

Bobby Plunkett
Bobby Plunkett

Posted on

function or const, which do you prefer? (TypeScript/JavaScript)

When it comes to writing a function, which style do you prefer?

const

const doSomethingCool: string = () => 'yes'
Enter fullscreen mode Exit fullscreen mode

OR

function

function doSomethingCool(): string {
  return 'yes';
}
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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 (16)

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

There are technical differences that should be considered over personal preferences:

  1. const prevents reassignment of the name while function does not.
  2. Using an arrow function doesn't have it's own lexical context, so it won't have a scoped this and can't be used as a constructor while function can be.
  3. A const arrow function needs to be declared before calling it, otherwise it's undefined
  4. A function can be declared after calling it.

Note you can also do:

const logWhatever = function( something ) { 
  console.log(something); 
}
Enter fullscreen mode Exit fullscreen mode

Which both prevents reassignment and creates a lexical context.

So it's a matter of needs on a given point on your software.

Collapse
 
buckldav profile image
David

In React, I tend to use function for components and const for like onSubmit handlers within those components. Just feels better to me for some reason :)

Collapse
 
brense profile image
Rense Bakker

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.

Collapse
 
joelbonetr profile image
JoelBonetR 🥇 • Edited

I think there's no need to read the whole line to know whether some const is a function or not.

 const myDog = 
Enter fullscreen mode Exit fullscreen mode
 const getUserById = 
Enter fullscreen mode Exit fullscreen mode

Read the comment I let above where I explain the technical insights on that so you can choose const or function whenever suits best 😊

Collapse
 
brense profile image
Rense Bakker
//Which is the function?
const alotofcharacters
function alotofcharacters
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇

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.

Thread Thread
 
brense profile image
Rense Bakker

facepalm alotofcharacters is not the name of the function... I should have replaced it with Chinese characters... How fast can you interpret Chinese?

Thread Thread
 
baharestani profile image
Daniel Baharestani • Edited

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:

// First few characters are enough to tell which one is function
const getSomethingFromSomewhereUnderCertianConditions
const SomethingFromSomewhereUnderCertianConditions
Enter fullscreen mode Exit fullscreen mode
Collapse
 
harithzainudin profile image
Muhammad Harith Zainudin

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!

Collapse
 
tobshub profile image
Tobani Esan-George

I'm thinking of going back to the function statement, in react especially. Mostly because you can do export default function MyFunction but have to put the default export on another line with the const style of function declarations.

Collapse
 
moopet profile image
Ben Sinclair

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.

Collapse
 
boxabirds profile image
Julian Harris • Edited

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 :) )

Collapse
 
robertgres profile image
Robert Gres

A few observations:

  • const doesn't prevent reassignments after it's imported in another module
  • lexical context doesn't matter unless this is used inside
  • sometimes procedural code is the best way to go, e.g. when writing scripts. Without hoisting it's all crap. Using function notation allows to invert code flow - to start from top-level calls and bindings on top and finish with details and junk at the bottom.
  • If you're improving performance or fixing memory leaks, good luck debugging call trees with all of those "anonymous" functions!
Collapse
 
samrocksc profile image
Sam Clark

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.

Collapse
 
tylim88 profile image
Acid Coder

const, no hoisting = no guessing = predictable

Collapse
 
howbizarre profile image
How Bizarre

And last but not least, always think about what the garbage collector will do. Functions and constants have different meanings and conditions for the GBc and when to remove them from memory.