Why I Prefer 'function' Declarations for Top-Level Symbols (But Won't Use Them Anymore)
Manuel Artero Anguita 🟨
Posted on October 23, 2024
Today, we’ve decided to use arrow functions exclusively at work.
We have a common ESLint config, and the team voted to unify this rule across all projects.
And honestly I'm not a fan of this particular rule
Personally... function
declarations feels more expressive, at least for top-level symbols:
some-screen-of-my-app.tsx
import {} ...
export function SomeScreen(props: Props) {
const { myContext } = useMyContext()
const [state, setState] = useState()
const doSomething = () => { ... }
const handleSomething = () => { ... }
return <>...</>
}
function SomeInternalComponent() { ... }
This is how i'm used to write components: declaring a function
feels like a chapter title in a novel.
function Chapter3(storySoFar: Props) {
// where the Hero meets the Villain
}
But I do understand the team need: depending on the original author of a module we might find at first level const () => {}
or function
.
The main argument is that "arrow functions are more readable" (which i disagree with)
import {} ...
const SomeInternalComponent = () => { ... }
export const SomeScreen = (props: Props) => {
const { myContext } = useMyContext()
const [state, setState] = useState()
const doSomething = () => { ... }
const handleSomething = () => { ... }
return <>...</>
}
I tried to find some technical advantage to support my preference... some nerd *pitimini* [ something small or insignificant ] that moves the balance on my benefit but since we all agree on the following:
- No Classes (just functions)
- No global stuff (modern modules)
- No
this
There are no significant differences between each one.
Diving into Details:
const foo = () => { ... }
- No hoisting
- function's name is derived from the variable's name (
"foo"
) - Can't be overwritten later like
foo=...
- Doesn't create the prototype object
foo.prototype
- Can't be used as a constructor
new foo()
- Doesn't have
arguments
-
this
value is defined by where the function is declared
function foo() { ... }
- Hoisting
- function name is obv.
- Can be overwritten like
foo = ...
- Creates the object prototype
foo.prototype
-
new
is allowed like:new foo()
(which would link the prototype) -
this
value is defined by how the function is called
In the end, I prefer the Superior Clarity of function
for top-level components, but the will of the many prevails.
Kidding, I will adapt. Having a unified style will help to maintain a cohesive codebase.
😭😭😭.
thanks for reading
Posted on October 23, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 23, 2024
August 25, 2024