Arrow vs Regular Functions
Not just shorter syntax -- arrows deliberately drop this, arguments, new and hoisting.
Syntax
const f = (a) => a * 2; // no this, no arguments
function g(a) { return a * 2; } // own this + argumentsAn arrow function is not merely a compact function. It removes several features on purpose, and those absences are exactly why it exists.
| Regular | Arrow | |
|---|---|---|
own this | yes (by call site) | no -- inherits lexically |
arguments | yes | no (use ...rest) |
usable with new | yes | no |
| hoisted | declarations are | no |
The decision rule
- Use an arrow for callbacks and any function that should keep the surrounding
this-- array methods, promise chains, class field handlers. - Use a regular function for object methods, prototype methods, constructors, and generators, where a dynamic
thisis the point.
this.items.map(x => this.format(x)); // arrow keeps this -- no bind neededExample
Loading editor…
Press Run to execute the code.
When to use it
- Use an arrow function inside setInterval in a class method so this stays bound to the instance.
- Define a method on an object with a regular function so it can use this to access sibling properties.
- Choose a regular function for a constructor because arrow functions cannot be used with new.
More examples
Arrow captures enclosing this
The arrow function inside setInterval inherits this from start(), keeping it bound to the Ticker instance.
class Ticker {
constructor() { this.ticks = 0; }
start() {
setInterval(() => { this.ticks++; }, 100); // arrow: this is Ticker
}
}
const t = new Ticker();
t.start();Regular function for object method
A regular function as an object method binds this to the object, making this.items work as expected.
const store = {
items: ["a", "b"],
count: function () { return this.items.length; } // regular: this is store
};
console.log(store.count()); // 2Arrow cannot be a constructor
Arrow functions lack a prototype and cannot be called with new; only regular functions can be constructors.
const Foo = () => {};
try {
new Foo(); // TypeError: Foo is not a constructor
} catch (e) {
console.log(e.message);
}
function Bar() { this.x = 1; }
console.log(new Bar().x); // 1
Discussion