Q8 of 40 · JavaScript
How do arrow functions differ from regular functions in JavaScript?
Short answer
Short answer: Arrow functions inherit `this` from the enclosing scope (lexical `this`) instead of binding it dynamically. They cannot be constructors, have no `arguments` object, and cannot be generators. Their concise syntax also makes inline callbacks more readable.
Detail
Arrow functions were introduced in ES6 and differ from regular functions in several important ways.
Lexical this: The most important difference. Regular functions bind this based on how they are called. Arrow functions capture the this from where they are defined, not where they are called. This makes them ideal for callbacks inside class methods where you want to retain the outer this.
No arguments object: Arrow functions do not have their own arguments object. Use rest parameters (...args) instead.
Cannot be constructors: Calling new ArrowFn() throws a TypeError. Arrow functions have no prototype property.
Cannot be generators: Arrow functions cannot use the function* syntax.
In test automation: Arrow functions are ubiquitous in Playwright and Cypress — page.$$eval('.row', rows => rows.map(r => r.textContent)), for example. Understanding lexical this prevents bugs in custom command or helper class methods that rely on closures.
// EXAMPLE
// Regular function: this is dynamic — breaks in callbacks
function Timer() {
this.seconds = 0;
setInterval(function() {
this.seconds++; // 'this' is undefined in strict mode
}, 1000);
}
// Arrow function: this is lexical — correct
function TimerFixed() {
this.seconds = 0;
setInterval(() => {
this.seconds++; // 'this' refers to TimerFixed instance
}, 1000);
}
// Concise syntax in array methods
const doubled = [1, 2, 3].map(n => n * 2); // [2, 4, 6]
const evens = [1, 2, 3].filter(n => n % 2 === 0); // [2]
// Single-expression implicit return
const square = n => n * n;