Funktionen Grundlagen in JavaScript
Funktionen Grundlagen
Funktionen sind wiederverwendbare Code-Blöcke. Sie sind eines der wichtigsten Konzepte in JavaScript und machen deinen Code organisiert, lesbar und wartbar.
Warum Funktionen?
Ohne Funktionen:
// Begrüßung für Max
console.log("Hallo Max!");
console.log("Willkommen auf unserer Seite!");
console.log("---");
// Begrüßung für Anna
console.log("Hallo Anna!");
console.log("Willkommen auf unserer Seite!");
console.log("---");
// Begrüßung für Tom
console.log("Hallo Tom!");
console.log("Willkommen auf unserer Seite!");
console.log("---");
Mit Funktionen:
function greet(name) {
console.log(`Hallo ${name}!`);
console.log("Willkommen auf unserer Seite!");
console.log("---");
}
greet("Max");
greet("Anna");
greet("Tom");
Vorteile:
- ✅ Weniger Wiederholung (DRY - Don’t Repeat Yourself)
- ✅ Leichter zu ändern (nur an einer Stelle)
- ✅ Besser lesbar
- ✅ Testbar
Funktionen deklarieren
Function Declaration
function sayHello() {
console.log("Hallo!");
}
// Aufrufen
sayHello(); // "Hallo!"
Function Expression
const sayHello = function() {
console.log("Hallo!");
};
sayHello();
Arrow Function (Modern!)
const sayHello = () => {
console.log("Hallo!");
};
// Kurzform bei einer Zeile
const sayHi = () => console.log("Hi!");
sayHello();
sayHi();
Parameter und Argumente
Parameter sind Eingaben für deine Funktion:
function greet(name) { // "name" ist der Parameter
console.log(`Hallo, ${name}!`);
}
greet("Max"); // "Max" ist das Argument
greet("Anna");
Mehrere Parameter
function createUser(name, age, city) {
console.log(`${name}, ${age} Jahre, wohnt in ${city}`);
}
createUser("Max", 25, "Berlin");
// "Max, 25 Jahre, wohnt in Berlin"
Default-Parameter
function greet(name = "Gast") {
console.log(`Hallo, ${name}!`);
}
greet(); // "Hallo, Gast!"
greet("Max"); // "Hallo, Max!"
// Komplexeres Beispiel
function createConfig(options = {}) {
const config = {
theme: options.theme || "light",
language: options.language || "de",
debug: options.debug ?? false
};
return config;
}
createConfig(); // { theme: "light", language: "de", debug: false }
createConfig({ theme: "dark" }); // { theme: "dark", language: "de", debug: false }
Rest-Parameter ...
Sammelt beliebig viele Argumente:
function sum(...numbers) {
let total = 0;
for (const num of numbers) {
total += num;
}
return total;
}
console.log(sum(1, 2)); // 3
console.log(sum(1, 2, 3, 4, 5)); // 15
// Mit normalen Parametern kombinieren
function greetAll(greeting, ...names) {
for (const name of names) {
console.log(`${greeting}, ${name}!`);
}
}
greetAll("Hallo", "Max", "Anna", "Tom");
// "Hallo, Max!"
// "Hallo, Anna!"
// "Hallo, Tom!"
Rückgabewerte mit return
Funktionen können Werte zurückgeben:
function add(a, b) {
return a + b;
}
const result = add(5, 3);
console.log(result); // 8
// In Berechnungen verwenden
const total = add(10, 20) + add(5, 5);
console.log(total); // 40
Frühe Returns
function divide(a, b) {
if (b === 0) {
return "Fehler: Division durch 0!"; // Früher Exit
}
return a / b;
}
console.log(divide(10, 2)); // 5
console.log(divide(10, 0)); // "Fehler: Division durch 0!"
Mehrere Werte zurückgeben
// Mit Object
function getUser() {
return {
name: "Max",
age: 25,
city: "Berlin"
};
}
const user = getUser();
console.log(user.name); // "Max"
// Mit Destructuring
const { name, age } = getUser();
console.log(name, age); // "Max" 25
// Mit Array
function getMinMax(numbers) {
return [Math.min(...numbers), Math.max(...numbers)];
}
const [min, max] = getMinMax([3, 1, 4, 1, 5, 9]);
console.log(min, max); // 1 9
Arrow Functions im Detail
Arrow Functions sind die moderne Art, Funktionen zu schreiben:
// Klassisch
function add(a, b) {
return a + b;
}
// Arrow Function
const add = (a, b) => {
return a + b;
};
// Kurzform (implicit return)
const add = (a, b) => a + b;
// Ein Parameter? Klammern optional
const double = x => x * 2;
// Kein Parameter? Leere Klammern
const getRandom = () => Math.random();
Wann welche Form?
// ✅ Einzeiler - Kurzform
const square = x => x * x;
const isEven = n => n % 2 === 0;
const greet = name => `Hallo, ${name}!`;
// ✅ Mehrere Zeilen - Mit Block
const processUser = (user) => {
const fullName = `${user.firstName} ${user.lastName}`;
const greeting = `Willkommen, ${fullName}!`;
return greeting;
};
// ✅ Object zurückgeben - Klammern um Object!
const createUser = (name, age) => ({
name,
age,
createdAt: new Date()
});
Scope (Gültigkeitsbereich)
Variablen haben einen Gültigkeitsbereich:
Global Scope
const globalVar = "Ich bin überall verfügbar";
function test() {
console.log(globalVar); // ✅ Funktioniert
}
test();
console.log(globalVar); // ✅ Funktioniert
Function Scope
function test() {
const localVar = "Nur in dieser Funktion";
console.log(localVar); // ✅ Funktioniert
}
test();
console.log(localVar); // ❌ ReferenceError!
Block Scope (let/const)
if (true) {
const blockVar = "Nur in diesem Block";
let anotherBlock = "Auch nur hier";
console.log(blockVar); // ✅ Funktioniert
}
console.log(blockVar); // ❌ ReferenceError!
// Deshalb kein var verwenden!
if (true) {
var leakyVar = "Ich lecke raus!";
}
console.log(leakyVar); // ⚠️ Funktioniert (schlecht!)
Scope Chain
Funktionen können auf äußere Variablen zugreifen:
const outer = "Außen";
function outerFunction() {
const middle = "Mitte";
function innerFunction() {
const inner = "Innen";
console.log(inner); // ✅ "Innen"
console.log(middle); // ✅ "Mitte"
console.log(outer); // ✅ "Außen"
}
innerFunction();
}
outerFunction();
Funktionen als Werte
In JavaScript sind Funktionen First-Class Citizens - sie können wie normale Werte behandelt werden:
In Variablen speichern
const myFunc = function() {
console.log("Hallo!");
};
const anotherRef = myFunc; // Referenz kopieren
anotherRef(); // "Hallo!"
Als Parameter übergeben
function doSomething(callback) {
console.log("Vor dem Callback");
callback();
console.log("Nach dem Callback");
}
doSomething(() => console.log("Ich bin der Callback!"));
// "Vor dem Callback"
// "Ich bin der Callback!"
// "Nach dem Callback"
Aus Funktionen zurückgeben
function createMultiplier(factor) {
return (number) => number * factor;
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
Praktische Beispiele
Validierungs-Funktionen
const isEmail = (email) => {
return email.includes("@") && email.includes(".");
};
const isStrongPassword = (password) => {
const minLength = password.length >= 8;
const hasNumber = /\d/.test(password);
const hasUpper = /[A-Z]/.test(password);
return minLength && hasNumber && hasUpper;
};
const isEmpty = (value) => {
return value === null || value === undefined || value === "";
};
// Verwendung
if (isEmpty(username)) {
console.log("Username erforderlich");
}
if (!isEmail(email)) {
console.log("Ungültige E-Mail");
}
if (!isStrongPassword(password)) {
console.log("Passwort zu schwach");
}
Array-Helfer
const sum = (numbers) => numbers.reduce((a, b) => a + b, 0);
const average = (numbers) => sum(numbers) / numbers.length;
const max = (numbers) => Math.max(...numbers);
const min = (numbers) => Math.min(...numbers);
const grades = [85, 90, 78, 92, 88];
console.log(`Summe: ${sum(grades)}`); // 433
console.log(`Durchschnitt: ${average(grades)}`); // 86.6
console.log(`Beste Note: ${max(grades)}`); // 92
console.log(`Schlechteste: ${min(grades)}`); // 78
Preis-Formatter
function formatPrice(amount, currency = "EUR", locale = "de-DE") {
return new Intl.NumberFormat(locale, {
style: "currency",
currency: currency
}).format(amount);
}
console.log(formatPrice(1234.56)); // "1.234,56 €"
console.log(formatPrice(1234.56, "USD", "en-US")); // "$1,234.56"
Event-Handler Factory
function createClickHandler(message) {
return function(event) {
console.log(message);
console.log("Geklickt auf:", event.target);
};
}
// Verwendung
button1.onclick = createClickHandler("Button 1 wurde geklickt");
button2.onclick = createClickHandler("Button 2 wurde geklickt");
Best Practices
1. Eine Funktion, eine Aufgabe
// ❌ Macht zu viel
function processUser(user) {
// Validieren
// Speichern
// E-Mail senden
// Logs schreiben
}
// ✅ Aufgeteilt
function validateUser(user) { /* ... */ }
function saveUser(user) { /* ... */ }
function sendWelcomeEmail(user) { /* ... */ }
function logUserCreation(user) { /* ... */ }
2. Aussagekräftige Namen
// ❌ Unklar
function proc(d) { }
function handle(x, y) { }
// ✅ Klar
function processOrder(orderData) { }
function calculateTax(price, taxRate) { }
3. Keine Seiteneffekte
// ❌ Ändert globalen State
let total = 0;
function addToTotal(amount) {
total += amount; // Seiteneffekt!
}
// ✅ Gibt neuen Wert zurück
function add(a, b) {
return a + b; // Keine Seiteneffekte
}
4. Wenige Parameter
// ❌ Zu viele Parameter
function createUser(name, age, city, email, phone, role) { }
// ✅ Options-Object
function createUser(options) {
const { name, age, city, email, phone, role } = options;
}
// Oder mit Destructuring
function createUser({ name, age, city = "Berlin", email, phone = null, role = "user" }) {
// ...
}
Zusammenfassung
| Konzept | Beispiel |
|---|---|
| Function Declaration | function name() {} |
| Function Expression | const name = function() {} |
| Arrow Function | const name = () => {} |
| Parameter | function greet(name) {} |
| Default-Parameter | function greet(name = "Gast") {} |
| Rest-Parameter | function sum(...nums) {} |
| Return | return value; |
| Scope | Global, Function, Block |
💡 Merke: Gute Funktionen sind kurz, machen eine Sache und haben aussagekräftige Namen. Nutze Arrow Functions für kurze Callbacks und normale Funktionen für komplexere Logik!