Discussion: Arrow Functions vs Traditional Functions
The style guide recommends using arrow functions for anonymous functions (Section 8.1). While I agree with this recommendation, I think it would be helpful to add more examples showing when traditional functions might still be preferred, such as:
- When you need the function to be hoisted
- When you need to use
thisbinding differently - When you need the
argumentsobject
What do you think about adding these clarifications?
This guide strictly forbids relying on hoisting, and you can use rest syntax if you need all the unnamed arguments.
Basically any time a function isn’t an inline callback, it should be a traditional function.
Yes, adding those clarifications would be helpful. While arrow functions are preferred for their conciseness, examples highlighting cases like hoisting, this binding, and use of arguments can provide important context and prevent misuse. It would make the style guide more complete and practical.
Arrow functions are expressions, not declarations, so they’re not hoisted. This matters in cases where function order is important.
Arrow functions and regular functions in JavaScript differ primarily in their syntax, this binding, and how they handle arguments. Arrow functions offer a more concise syntax, especially for single-line functions, and automatically bind this to the surrounding scope, unlike regular functions which have dynamic this binding.
If you follow this guide, you NEVER rely on hoisting, so any function must be declared higher in the file than where it's used.
@fisker0303 I think arrow functions, as callbacks, are a separate use case where hoisting isn’t typically relevant, and their lexical 'this' plus concise syntax are ideal. Still, examples of when traditional functions are necessary could add clarity, which they already mention in previous sections. Also, you would never rely on hoisting if you follow this guide
Thanks everyone for the clarifications — I agree that explicit examples of when traditional functions are still required would make the guide even more practical. For instance: // Needs traditional function (access to arguments) function sum() { return Array.from(arguments).reduce((a, b) => a + b, 0); }
// Arrow function won't work the same way const sumArrow = () => { console.log(arguments); // ReferenceError };
For instance, when defining methods in prototype-based libraries or classes, traditional functions are often clearer due to their dynamic this behavior!!
2015 was a long time ago; nobody should be defining classes without class ever again.
That’s a great point — I completely agree. While the style guide correctly emphasizes using arrow functions for cleaner and more concise anonymous functions, it would definitely add clarity to include examples showing when traditional function declarations or expressions are more suitable.
Specifically:
Hoisting: Traditional functions allow hoisting, which can improve readability or structure in certain cases (e.g., when defining helper functions below their usage).
this binding: Arrow functions don’t have their own this, so when a function needs dynamic this context — such as in class methods, event handlers, or object methods — the traditional function syntax is preferable.
arguments object: Arrow functions don’t have their own arguments object, so traditional functions are still needed when working with variadic functions that rely on it.
Adding these clarifications (perhaps with short code examples) would make the style guide more comprehensive and practical for developers learning when not to use arrow functions.
This guide strictly forbids relying on hoisting ever - always define things before they're used.
Class methods can't use arrow functions, object methods should use concise method syntax, and event handlers should use the event object instead of the receiver.
re arguments, (...args) => {}.
This stuff is already covered by the guide.
Thanks everyone — this has been a really insightful discussion.
I agree that the guide already covers the rules around hoisting, this, and arguments — but in practice, many developers (especially those reading the guide for the first time) don’t always connect those rules with when they should actually prefer traditional functions.
A small “When not to use arrow functions” reference box (with minimal examples) could make these existing rules more discoverable without adding any new concepts. Something like:
// 1. Hoisting — always declare before use (no relying on hoisting)
helper(); // avoid
function helper() {} // prefer declaring first
// 2. Class methods — use standard syntax
class Foo {
bar() { /* dynamic this */ }
// bar = () => {} not recommended
}
// 3. Object methods — concise method syntax
const obj = {
tick() {}, // recommended
// tick: () => {} not recommended
};
// 4. Variadic functions — use rest params instead of `arguments`
const sum = (...args) => args.reduce((a, b) => a + b); // recommended
function legacy() { return Array.from(arguments) } // not recommended
This kind of quick-reference section wouldn’t change the rules — it would just make the intent more explicit and easier to apply at a glance.
If the team is open to it, I’d be happy to open a small PR adding this to the relevant section of the guide.
Yes, these clarifications should definitely be added.
- Arrow functions are great by default, but traditional functions are still needed when:
- You rely on hoisting
- You need a dynamic this
You use the arguments object
Nobody using this guide should ever be relying on hoisting.