Skip to content

Kapitel 5: Arrow Functions (Pfeilfunktionen)

5.1 Arrow Function Grundlagen

📦 Was ist eine Arrow Function?

Arrow Functions (Pfeilfunktionen) sind eine kompaktere Syntax für Funktionsausdrücke in ES6.

javascript
// ❌ Alte Syntax (ES5) - Funktionsausdruck
var add = function(a, b) {
  return a + b;
};

// ✅ Neue Syntax (ES6) - Arrow Function
const add = (a, b) => {
  return a + b;
};

// ✅ Noch kürzer (siehe 5.2)
const addKurz = (a, b) => a + b;

🔤 Grundlegende Syntax

javascript
// Vollständige Syntax
const funktion1 = (param1, param2) => {
  // Funktionskörper
  return ergebnis;
};

// Einzelner Parameter - Klammern optional
const funktion2 = param => {
  return param * 2;
};

// Kein Parameter - leere Klammern
const funktion3 = () => {
  return "Hallo";
};

// Einzelner Ausdruck - Klammern und return weglassen
const funktion4 = (a, b) => a + b;

// Einzelner Rückgabewert (Objekt) - in Klammern
const funktion5 = (id, name) => ({ id, name });

5.2 Kurzschreibweise (Klammern weglassen)

✂️ Regel 1: Einzelner Parameter

javascript
// ✅ Klammern um Parameter weglassen
const double = n => n * 2;

console.log(double(5)); // 10

// ❌ Mehrere Parameter - Klammern nötig
const add = (a, b) => a + b;

✂️ Regel 2: Einzelne Anweisung (Implicit Return)

javascript
// ✅ Geschweifte Klammern und 'return' weglassen
const square = n => n * n;

console.log(square(4)); // 16

// Mit Block-Körper (Klammern nötig)
const squareExplicit = n => {
  return n * n;
};

✂️ Regel 3: Objekt zurückgeben

javascript
// ❌ Falsch - JS denkt, {} ist ein Block
const createUser = (id, name) => { id, name };

// ✅ Richtig - Objekt in Klammern einschließen
const createUser = (id, name) => ({ id, name });

console.log(createUser(1, "Max")); // { id: 1, name: "Max" }

🎯 Vollständige Vergleichstabelle

SzenarioES5 (Funktionsausdruck)ES6 (Arrow Function)
Zwei Parameter, returnfunction(a,b){return a+b;}(a,b)=>a+b
Ein Parameter, returnfunction(n){return n*2;}n=>n*2
Kein Parameterfunction(){return 42;}()=>42
Objekt zurückgebenfunction(){return{x:1};}()=>({x:1})

5.3 Arrow Functions this (statisch, keine Änderung)

🔑 Das this-Problem in ES5

In normalen Funktionen wird this durch den Aufrufkontext bestimmt.

javascript
// ❌ Problem in ES5
const person = {
  name: "Max",
  hobbies: ["Sport", "Lesen"],
  printHobbies: function() {
    this.hobbies.forEach(function(hobby) {
      console.log(`${this.name} mag ${hobby}`); 
      // ❌ this.name ist undefined (this bezieht sich auf window/global)
    });
  }
};

person.printHobbies();

Lösung in ES5: self = this oder bind()

javascript
// ES5 Lösung 1: self = this
printHobbies: function() {
  var self = this;
  this.hobbies.forEach(function(hobby) {
    console.log(`${self.name} mag ${hobby}`);
  });
}

// ES5 Lösung 2: bind()
printHobbies: function() {
  this.hobbies.forEach(function(hobby) {
    console.log(`${this.name} mag ${hobby}`);
  }.bind(this));
}

✅ Arrow Functions lösen das this-Problem

Arrow Functions haben kein eigenes this. Sie erben this aus dem umgebenden Scope (lexikalisches this).

javascript
// ✅ Arrow Function - this wird vererbt
const person = {
  name: "Max",
  hobbies: ["Sport", "Lesen"],
  printHobbies: function() {
    this.hobbies.forEach(hobby => {
      console.log(`${this.name} mag ${hobby}`); 
      // ✅ this.name = "Max" (this von printHobbies)
    });
  }
};

person.printHobbies();
// Max mag Sport
// Max mag Lesen

🔍 Detaillierter Vergleich: this

Funktionstypthis Wert
Normale FunktionDynamisch (wer aufruft)
Arrow FunctionLexikalisch (umgebender Scope)
Methode in ObjektDas Objekt
Event Handler (normale Funktion)Das DOM-Element
Event Handler (Arrow Function)Das umgebende this

🌐 Beispiel: Event Handler

javascript
// ❌ Normale Funktion - this = das DOM-Element
button.addEventListener("click", function() {
  console.log(this); // Das <button> Element
});

// ✅ Arrow Function - this = umgebendes this
class MyComponent {
  constructor() {
    this.count = 0;
    this.button = document.querySelector("button");
    
    // Arrow Function beibehält this von der Klasse
    this.button.addEventListener("click", () => {
      this.count++;
      console.log(this.count); // ✅ Funktioniert
    });
  }
}

5.4 Was Arrow Functions NICHT können (kein Konstruktor, kein arguments)

❌ Einschränkung 1: Kein Konstruktor

Arrow Functions können nicht mit new aufgerufen werden.

javascript
// ✅ Normale Funktion - kann Konstruktor sein
function Person(name) {
  this.name = name;
}
const p1 = new Person("Max");
console.log(p1.name); // "Max"

// ❌ Arrow Function - kein Konstruktor
const PersonArrow = (name) => {
  this.name = name;
};
const p2 = new PersonArrow("Max"); 
// ❌ TypeError: PersonArrow is not a constructor

❌ Einschränkung 2: Kein eigenes arguments

Arrow Functions haben kein eigenes arguments Objekt.

javascript
// ✅ Normale Funktion - hat arguments
function demo1() {
  console.log(arguments); // { '0': 1, '1': 2 }
}
demo1(1, 2);

// ❌ Arrow Function - kein arguments
const demo2 = () => {
  console.log(arguments); 
  // ❌ ReferenceError (oder arguments vom umgebenden Scope)
};
demo2(1, 2);

// ✅ Lösung: Rest-Parameter verwenden
const demo3 = (...args) => {
  console.log(args); // [1, 2] ✅
};
demo3(1, 2);

❌ Einschränkung 3: Kein eigenes prototype

javascript
// ✅ Normale Funktion - hat prototype
function NormalFunction() {}
console.log(NormalFunction.prototype); // {}

// ❌ Arrow Function - kein prototype
const ArrowFunction = () => {};
console.log(ArrowFunction.prototype); // undefined

📋 Zusammenfassung: Arrow Function Einschränkungen

EinschränkungNormale FunktionArrow Function
Konstruktor (new)
Eigenes arguments
Eigenes this❌ (erbt)
Eigenes prototype

5.5 Praxis: Code in Array-Methoden vereinfachen

🎯 Beispiel 1: map() vereinfachen

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

// ❌ ES5 - umständlich
const doubled1 = numbers.map(function(n) {
  return n * 2;
});

// ✅ ES6 - kompakt
const doubled2 = numbers.map(n => n * 2);

console.log(doubled2); // [2, 4, 6, 8, 10]

🎯 Beispiel 2: filter() vereinfachen

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

// ✅ Arrow Function
const even = numbers.filter(n => n % 2 === 0);

console.log(even); // [2, 4, 6]

🎯 Beispiel 3: reduce() vereinfachen

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

// ✅ Arrow Function
const sum = numbers.reduce((total, n) => total + n, 0);

console.log(sum); // 15

🎯 Beispiel 4: sort() vereinfachen

javascript
const numbers = [5, 3, 8, 1, 4];

// ✅ Arrow Function
const sorted = numbers.sort((a, b) => a - b);

console.log(sorted); // [1, 3, 4, 5, 8]

🎯 Beispiel 5: Verkettung (Chaining)

javascript
const users = [
  { name: "Max", alter: 25, aktiv: true },
  { name: "Erika", alter: 30, aktiv: false },
  { name: "Julia", alter: 28, aktiv: true }
];

// ✅ Verkettung mit Arrow Functions
const aktiveUserNamen = users
  .filter(user => user.aktiv)
  .map(user => user.name)
  .sort((a, b) => a.localeCompare(b));

console.log(aktiveUserNamen); // ["Julia", "Max"]

5.6 Normale Funktion vs Arrow Function Zusammenfassung

📊 Wann welche Funktion verwenden?

SzenarioEmpfehlungBegründung
Objekt-MethodeNormale Funktionthis soll das Objekt sein
Event HandlerArrow Functionthis aus umgebendem Scope erben
Array-Methoden (map, filter, etc.)Arrow FunctionKompakte Syntax
Klassen-KonstruktorNormale Funktionnew benötigt
Prototype-MethodenNormale Funktionthis soll das Instanz-Objekt sein
IIFE (Immediately Invoked)Beide möglichGeschmackssache
Callback mit eigenem thisNormale Funktionthis soll dynamisch sein

📝 Code-Beispiel: Objekt-Methode

javascript
// ✅ Richtig - Normale Funktion für Methode
const person = {
  name: "Max",
  greet: function() {  // oder Kurzschreibweise: greet() { ... }
    console.log(`Hallo, ich bin ${this.name}`);
  }
};

person.greet(); // "Hallo, ich bin Max"

// ❌ Falsch - Arrow Function für Methode
const personFalsch = {
  name: "Max",
  greet: () => {
    console.log(`Hallo, ich bin ${this.name}`); 
    // ❌ this ist nicht das Objekt!
  }
};

📝 Code-Beispiel: Klassen

javascript
// ✅ Richtig - Normale Funktion für Klassen-Methoden
class Person {
  constructor(name) {
    this.name = name;
  }
  
  greet() {  // Normale Methode
    console.log(`Hallo, ich bin ${this.name}`);
  }
}

// ✅ Richtig - Arrow Function für Event Handler in Klassen
class MyComponent {
  constructor() {
    this.count = 0;
    this.button = document.querySelector("button");
  }
  
  init() {
    // Arrow Function behält this bei
    this.button.addEventListener("click", () => {
      this.count++;
      console.log(this.count);
    });
  }
}

🎉 Zusammenfassung

In diesem Kapitel hast du gelernt:

  • ✅ Arrow Function Grundlagen und Syntax
  • ✅ Kurzschreibweise (Klammern weglassen, implicit return)
  • this-Verhalten (lexikalisch, statisch)
  • ✅ Einschränkungen (kein Konstruktor, kein arguments)
  • ✅ Praxisanwendung (Array-Methoden vereinfachen)
  • ✅ Wann normale Funktion vs. Arrow Function verwenden

📝 Übung

  1. Arrow Function Grundlagen:

    javascript
    // Schreibe eine Arrow Function 'multiply', die zwei Zahlen multipliziert
  2. Array-Methoden mit Arrow Functions:

    javascript
    const numbers = [1, 2, 3, 4, 5];
    // Verwende map() und eine Arrow Function, um jedes Element zu verdoppeln
  3. this-Verhalten:

    javascript
    const obj = {
      value: 42,
      getValue: function() {
        // Erstelle eine Arrow Function in setTimeout, die this.value ausgibt
      }
    };
    obj.getValue();

➡️ Nächstes Kapitel

In Kapitel 6 lernen wir Template Strings (Template Literals) - eine elegante Möglichkeit, Strings zu erstellen und Variablen einzufügen!

Frei für alle Anfänger