- Sync/async generator forms
- Not constant, can be reassigned
- Hoisting can result in runtime exceptions (https://twitter.com/OliverJAsh/status/1247240674388447234)
- Hoisting
- Arguably simpler, same construct for creating values regardless of type (
var
,const
,let
) - Can use with TypeScript type annotations e.g.
const reducer: Reducer = () => {}
- Automatic
this
binding (not to encourage use ofthis
, though…) - More concise thanks to arrow syntax
- If you want to use function composition i.e.
flow
, you have to use an expression. Furthermore, TypeScript can infer types of composed functions, e.g.const aToC = flow(a, b, c); // (a: A) => C
.
- No sync/async generator forms
- No hoisting
The thing I personally dislike about hoisting is it doesn't enforce any direction in the code. Definitions may appear above or below. Without hoisting, it's always one direction: details -> derived values.
A subjective con about this is that it's often used without additional type annotations for the return type, resulting in excess property checks not kicking in.