🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Understand arrow function syntax and benefits
  • Know when to use arrow functions vs regular functions
  • Understand lexical this binding in arrow functions
  • Use arrow functions with array methods
  • Avoid common arrow function pitfalls
  • Write cleaner, more concise code

📚 Arrow Function Syntax

Basic Syntax

// Regular function
function add(a, b) {
    return a + b;
}

// Arrow function
const add = (a, b) => a + b;

// Single parameter (parentheses optional)
const square = x => x * x;

// No parameters
const greet = () => "Hello World";

// Multiple statements
const process = (data) => {
    const result = data.map(item => item * 2);
    return result.filter(item => item > 10);
};

Array Methods with Arrow Functions

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

// Map
const doubled = numbers.map(n => n * 2);

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

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

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

🔗 Lexical this Binding

The Problem with Regular Functions

class Timer {
    constructor() {
        this.seconds = 0;
    }

    start() {
        setInterval(function() {
            this.seconds++; // Error! 'this' is undefined
            console.log(this.seconds);
        }, 1000);
    }
}

Solution with Arrow Functions

class Timer {
    constructor() {
        this.seconds = 0;
    }

    start() {
        setInterval(() => {
            this.seconds++; // Works! 'this' refers to Timer instance
            console.log(this.seconds);
        }, 1000);
    }
}

🎯 Practice Exercises

Exercise 1: Array Processing

Transform an array of user objects:

Solution:

const users = [
    { name: 'Alice', age: 30, active: true },
    { name: 'Bob', age: 25, active: false },
    { name: 'Charlie', age: 35, active: true }
];

// Get names of active users
const activeUserNames = users
    .filter(user => user.active)
    .map(user => user.name);

console.log(activeUserNames); // ['Alice', 'Charlie']

// Calculate average age of active users
const averageAge = users
    .filter(user => user.active)
    .reduce((sum, user, index, array) => {
        sum += user.age;
        return index === array.length - 1 ? sum / array.length : sum;
    }, 0);

console.log(averageAge); // 32.5

Exercise 2: Event Handlers

Create event handlers using arrow functions:

Solution:

class Button {
    constructor(element) {
        this.element = element;
        this.clickCount = 0;
        this.setupEventHandlers();
    }

    setupEventHandlers() {
        // Arrow function preserves 'this' context
        this.element.addEventListener('click', () => {
            this.clickCount++;
            this.updateDisplay();
        });

        // Mouse enter/leave handlers
        this.element.addEventListener('mouseenter', () => {
            this.element.style.backgroundColor = '#f0f0f0';
        });

        this.element.addEventListener('mouseleave', () => {
            this.element.style.backgroundColor = '';
        });
    }

    updateDisplay() {
        this.element.textContent = `Clicked ${this.clickCount} times`;
    }
}

🚨 Common Pitfalls

1. Don't Use Arrow Functions for Methods

// Wrong - arrow function as method
const obj = {
    name: 'Alice',
    greet: () => {
        console.log(`Hello, I'm ${this.name}`); // 'this' is not obj
    }
};

// Right - regular function as method
const obj = {
    name: 'Alice',
    greet() {
        console.log(`Hello, I'm ${this.name}`); // 'this' is obj
    }
};

2. Don't Use Arrow Functions for Constructors

// Wrong - arrow functions can't be constructors
const Person = (name) => {
    this.name = name; // Error!
};

// Right - use regular function
function Person(name) {
    this.name = name;
}

3. Don't Use Arrow Functions for Generators

// Wrong - arrow functions can't be generators
const generator = *() => {
    yield 1;
    yield 2;
};

// Right - use regular function
function* generator() {
    yield 1;
    yield 2;
}

🎯 Key Takeaways

  1. Arrow functions provide concise syntax
  2. Lexical this binding solves context issues
  3. Array methods work great with arrow functions
  4. Don't use arrow functions for methods or constructors
  5. Use arrow functions for callbacks and short functions

🚀 Next Steps

Great! You now understand arrow functions deeply. In the next lesson, we'll learn about:

  • Default parameters - providing fallback values
  • Optional chaining - safe property access
  • Nullish coalescing - handling null/undefined values

Next Lesson: Lesson 2: Default Parameters & Optional Chaining