← JS Mastery | Module 3: Functions Arrow Functions & this Binding
Module 3

Arrow Functions & this Binding

⏱ 20 min read ● Intermediate 🆓 Free

Arrow Functions — ES6 Syntax

Arrow functions are a more concise syntax for writing functions. They were introduced in ES6 and have become the default choice for most JavaScript developers — but they have important differences from regular functions, especially regarding this.

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

// Arrow function — equivalent:
const add = (a, b) => {
  return a + b;
};

// Concise body — implicit return when one expression:
const add = (a, b) => a + b;

// Single parameter — parentheses optional:
const double = n => n * 2;
const square = n => n ** 2;

// No parameters — empty parens required:
const greet = () => "Hello!";
const now = () => new Date();

// Returning an object — wrap in parentheses!
const makeUser = (name, age) => ({ name, age });
// Without parens, { would be interpreted as function body

// Multi-line still needs braces and return:
const processData = (data) => {
  const filtered = data.filter(Boolean);
  const doubled = filtered.map(n => n * 2);
  return doubled;
};

Arrow Functions with Array Methods

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

// Arrow functions shine with array methods:
const doubled = numbers.map(n => n * 2);
const odds = numbers.filter(n => n % 2 !== 0);
const sum = numbers.reduce((acc, n) => acc + n, 0);
const firstBig = numbers.find(n => n > 3);
const hasZero = numbers.some(n => n === 0);

// Chaining:
const result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  .filter(n => n % 2 === 0)    // [2,4,6,8,10]
  .map(n => n * n)              // [4,16,36,64,100]
  .filter(n => n < 50);         // [4,16,36]

// Compare: with regular functions (verbose)
const doubled2 = numbers.map(function(n) { return n * 2; });
// vs arrow (clean):
const doubled3 = numbers.map(n => n * 2);

The this Keyword — Critical Difference

The most important difference between arrow functions and regular functions is how they handle this. Arrow functions don't have their own this — they inherit it from the surrounding scope.

// Regular function — 'this' depends on how the function is called
const obj = {
  name: "Alice",
  greet: function() {
    console.log(`Hello, I'm ${this.name}`);  // "Hello, I'm Alice"
  }
};
obj.greet(); // 'this' = obj

// Arrow function — 'this' is inherited from outer scope
const obj2 = {
  name: "Bob",
  greet: () => {
    console.log(`Hello, I'm ${this.name}`);  // "Hello, I'm undefined"
    // 'this' here is the outer scope (window/global), not obj2!
  }
};
obj2.greet(); // Problem!

// This is why arrow functions are BAD for object methods
// but GREAT for callbacks inside methods:
const counter = {
  count: 0,
  start: function() {
    // Arrow function inherits 'this' from start() method:
    setInterval(() => {
      this.count++;  // 'this' correctly refers to counter
      console.log(this.count);
    }, 1000);
    
    // Regular function would lose 'this':
    // setInterval(function() {
    //   this.count++;  // 'this' is window/undefined — BUG!
    // }, 1000);
  }
};

When to Use Each

Use CaseArrow FunctionRegular Function
Array methods (map, filter)✓ PreferredWorks
Object methods✗ Avoid (this)✓ Use this
Callbacks✓ PreferredWorks
Constructors (new)✗ Cannot✓ Yes
Event handlersSituational✓ If need this
Generators✗ Cannot✓ Yes

⚡ Key Takeaways

🎯 Practice Exercises

EXERCISE 1

Rewrite these regular functions as arrow functions with implicit returns: (1) function double(n) { return n*2; }, (2) function isEven(n) { return n%2===0; }, (3) a function that returns an object with name and age.

EXERCISE 2

Create an object timer with a count property and a start method. Inside start, use setTimeout with an arrow function to increment count after 1 second. Why does it work with arrow but not regular function?

← Function Basics