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
Top comments (3)
very interesting post!
function
hoisting is a trivial matter as unlikevar
hoisting, here we don't have to worry about an unintended value propagating through the code at run time (as can easily happen withvar
hoisting when the hoisted var gets set toundefined
at start of function). A hoistedfunction
identifier points to the function itself (rather, to the closure of the function) from the very beginning.Given that you sensibly ban
this
and classes in your code, (and sothis
binding shouldn't matter), I think arrow functions have a slight edge as noprototype
is created (none is needed) andnew
is not allowed (which reinforces the convention of not creating classes).Also, I think it's nice that arrow function's variable cannot be overwritten like
function
can if we always usingconst
when defining arrow functions.Not having
arguments
is perhaps not a big deal. With rest parameters (...params
) available, I have never quite needed to usearguments
.Not having an obvious name is a bit of a red herring for JS functions I think: when you export or import them, you can given them any name. Within a file, the variable to which the function is assigned can be reasonably seen as the name of the function..
For obvious reasons arrow functions much better for being returned from other functions as not complication of
prototype
orthis
binding.Therefore I think overall arrow function much better.
Sadly I am too attached to
function
and still use them. Your post is forcing me to reevaluate my inertia. Maybe from tomorow, I will only ever use arrow functions. Thanks for pointing out this can be reinforced through ESLint.Thanks for commenting @nausaf !!
Always a pleasure reading your posts Manuel!