Episode 9 of 11

Arrow Functions

Master arrow functions — concise syntax, implicit returns, and how 'this' binding differs from regular functions.

Arrow Functions

Arrow functions (=>) are a concise syntax for writing functions. Beyond brevity, they have a key difference: they don't have their own this — they inherit it from the surrounding scope.

Basic Syntax

// Traditional function
const greet = function(name) {
    return `Hello, ${name}!`;
};

// Arrow function
const greet = (name) => {
    return `Hello, ${name}!`;
};

// With a single parameter, parentheses are optional
const greet = name => {
    return `Hello, ${name}!`;
};

Implicit Return

If the function body is a single expression, you can omit the braces and return keyword:

// Explicit return (with braces)
const double = (n) => {
    return n * 2;
};

// Implicit return (single expression)
const double = n => n * 2;

// More examples:
const isEven = n => n % 2 === 0;
const fullName = (first, last) => `${first} ${last}`;
const square = x => x ** 2;

Returning Objects

To return an object literal implicitly, wrap it in parentheses:

// ❌ This creates a code block, not an object:
const getUser = () => { name: "Alice", age: 25 };

// ✅ Wrap in parentheses for implicit object return:
const getUser = () => ({ name: "Alice", age: 25 });

Arrow Functions in Array Methods

This is where arrows truly shine:

const numbers = [1, 2, 3, 4, 5];

// Map
const doubled = numbers.map(n => n * 2);
// [2, 4, 6, 8, 10]

// Filter
const evens = numbers.filter(n => n % 2 === 0);
// [2, 4]

// Reduce
const sum = numbers.reduce((total, n) => total + n, 0);
// 15

// Find
const firstBig = numbers.find(n => n > 3);
// 4

// Sort
const sorted = [...numbers].sort((a, b) => b - a);
// [5, 4, 3, 2, 1]

// Chain
const result = numbers
    .filter(n => n > 2)
    .map(n => n * 10)
    .reduce((sum, n) => sum + n, 0);
// 120

The 'this' Difference

Regular functions have their own this. Arrow functions inherit this from the enclosing scope:

// Regular function — 'this' problem:
const timer = {
    seconds: 0,
    start() {
        setInterval(function() {
            this.seconds++;  // ❌ 'this' is the Window, not timer!
            console.log(this.seconds);
        }, 1000);
    }
};

// Arrow function — 'this' is inherited:
const timer = {
    seconds: 0,
    start() {
        setInterval(() => {
            this.seconds++;  // ✅ 'this' is timer (inherited from start())
            console.log(this.seconds);
        }, 1000);
    }
};

When NOT to Use Arrow Functions

SituationUseWhy
Object methodsRegular functionArrow would inherit wrong this
Event handlers (DOM)Regular or arrowArrow won't have this = element
ConstructorsRegular functionArrow functions can't be used with new
Prototype methodsRegular functionNeed dynamic this binding
// ❌ Arrow as object method — wrong 'this':
const person = {
    name: "Alice",
    greet: () => {
        console.log(`Hi, I'm ${this.name}`);  // this.name is undefined!
    }
};

// ✅ Regular method shorthand:
const person = {
    name: "Alice",
    greet() {
        console.log(`Hi, I'm ${this.name}`);  // "Hi, I'm Alice" ✅
    }
};

Syntax Variations

ParametersSyntax
No parameters() => expression
One parameterx => expression
Multiple parameters(x, y) => expression
Multi-line body(x) => { statements; return value; }
Return object() => ({ key: value })

Key Takeaways

  • Arrow functions use => syntax — shorter than function
  • Single expressions can implicitly return (no braces or return)
  • Wrap object literals in parentheses for implicit return
  • Arrows don't have their own this — they inherit from the enclosing scope
  • Perfect for callbacks, array methods, and short inline functions
  • Don't use for object methods, constructors, or when you need dynamic this