JavaScript - Funktionen

-

Kernfunktionen

JavaScript verfügt über mehrere Kernfunktionen, die es zu einer leistungsstarken und flexiblen Programmiersprache für die Webentwicklung machen. Zu diesen Funktionen gehören Variablen und Datentypen, Operatoren, Kontrollfluss und Funktionen.

Variablen und Datentypen

In JavaScript können Sie Variablen mit den Schlüsselwörtern var, let oder const deklarieren. var ist die traditionelle Art, Variablen zu deklarieren, während let und const in ES6 (ECMAScript 2015) eingeführt wurden, um Block-Scoping und Unveränderlichkeit zu ermöglichen.

JavaScript hat mehrere primitive Datentypen:

Datentyp Beschreibung
number Stellt numerische Werte dar, sowohl Ganzzahlen als auch Gleitkommazahlen
string Stellt Textdaten dar, in einfachen oder doppelten Anführungszeichen eingeschlossen
boolean Stellt einen logischen Wert dar, entweder true oder false
null Stellt einen absichtlichen Nicht-Wert oder Nullwert dar
undefined Stellt eine Variable dar, die deklariert wurde, aber der kein Wert zugewiesen wurde

JavaScript hat auch einen object Datentyp, der Sammlungen von Schlüssel-Wert-Paaren oder komplexere Strukturen enthalten kann.

JavaScript ist eine dynamisch typisierte Sprache, was bedeutet, dass Variablen Werte jedes Datentyps enthalten können und der Typ einer Variable sich während der Laufzeit ändern kann. Diese Flexibilität wird durch Typumwandlung und Konvertierung erreicht, wobei JavaScript automatisch Werte von einem Typ in einen anderen umwandelt, wenn es erforderlich ist.

Operatoren

JavaScript bietet eine Reihe von Operatoren für die Durchführung von Operationen mit Werten:

  • Arithmetische Operatoren: +, -, *, /, %, ++, --
  • Zuweisungsoperatoren: =, +=, -=, *=, /=, %=
  • Vergleichsoperatoren: ==, ===, !=, !==, >, <, >=, <=
  • Logische Operatoren: &&, ||, !
  • Ternärer Operator: Bedingung ? Wert1 : Wert2

Kontrollfluss

JavaScript bietet mehrere Kontrollflussanweisungen, mit denen Sie die Ausführung von Code basierend auf bestimmten Bedingungen steuern oder Codeblöcke mehrmals wiederholen können.

  • if...else Anweisungen: Führen einen Codeblock aus, wenn eine bestimmte Bedingung wahr ist, oder einen anderen Codeblock, wenn die Bedingung falsch ist
  • switch Anweisung: Wertet einen Ausdruck aus und führt den entsprechenden Codeblock basierend auf dem übereinstimmenden Fall aus
  • for Schleife: Wiederholt einen Codeblock für eine bestimmte Anzahl von Malen
  • while und do...while Schleifen: Wiederholen einen Codeblock, solange eine bestimmte Bedingung wahr ist
  • break und continue Anweisungen: Ändern den Ablauf von Schleifen, indem sie die Schleife beenden oder zur nächsten Iteration springen

Funktionen

Funktionen sind wiederverwendbare Codeblöcke, die bestimmte Aufgaben ausführen. In JavaScript können Sie Funktionen mit dem Schlüsselwort function gefolgt vom Funktionsnamen und einer Reihe von Klammern mit optionalen Parametern definieren.

Beispiel: Funktionsdeklaration

function greet(name) {
  console.log("Hallo, " + name + "!");
}

Funktionen können Parameter als Eingabe akzeptieren und Werte mit dem Schlüsselwort return zurückgeben. Sie können durch ihren Namen gefolgt von Klammern mit eventuell erforderlichen Argumenten aufgerufen werden.

JavaScript unterstützt auch Funktionsausdrücke, bei denen Funktionen Variablen zugewiesen oder als Argumente an andere Funktionen übergeben werden können.

Beispiel: Funktionsausdruck

const square = function(x) {
  return x * x;
};

Pfeilfunktionen, die in ES6 eingeführt wurden, bieten eine prägnante Syntax für die Definition von Funktionen, insbesondere wenn sie als Callbacks oder in funktionalen Programmiermustern verwendet werden.

Beispiel: Pfeilfunktion

const multiply = (a, b) => a * b;

Diese Kernfunktionen bilden die Grundlage von JavaScript und sind für das Schreiben von einfachen bis komplexen Programmen in der Webentwicklung unerlässlich. Das Verständnis und die Beherrschung dieser Funktionen ermöglichen es Ihnen, dynamische und interaktive Webanwendungen zu erstellen.

Erweiterte Funktionen

JavaScript bietet viele fortgeschrittene Funktionen, mit denen Sie komplexeren und effizienteren Code schreiben können. Zu diesen Funktionen gehören Objekte und Arrays, Klassen und Vererbung, asynchrone Programmierung und Fehlerbehandlung.

Objekte und Arrays

Objekte und Arrays sind wichtige Datenstrukturen in JavaScript. Objekte speichern Sammlungen von Schlüssel-Wert-Paaren, während Arrays geordnete Listen von Werten speichern.

Um ein Objekt zu erstellen, können Sie die Objektliteral-Notation oder den Object-Konstruktor verwenden. Sie können auf Objekteigenschaften zugreifen und diese ändern, indem Sie die Punkt-Notation oder die Klammer-Notation verwenden.

Beispiel: Erstellen und Zugreifen auf Objekteigenschaften

const person = {
  name: "John",
  age: 30,
  city: "New York"
};

console.log(person.name); // Ausgabe: "John"
person.age = 31;
console.log(person["city"]); // Ausgabe: "New York"

Arrays werden mit der Array-Literal-Notation oder dem Array-Konstruktor erstellt. Sie können auf Array-Elemente zugreifen und diese ändern, indem Sie deren Index verwenden.

Beispiel: Erstellen und Zugreifen auf Array-Elemente

const fruits = ["apple", "banana", "orange"];

console.log(fruits[0]); // Ausgabe: "apple"
fruits[1] = "grape";
console.log(fruits); // Ausgabe: ["apple", "grape", "orange"]

Objekte und Arrays verfügen über integrierte Methoden, mit denen Sie häufige Operationen durchführen können, wie das Hinzufügen oder Entfernen von Elementen, das Suchen nach Werten und das Ändern von Daten.

JavaScript unterstützt auch Destrukturierung, mit der Sie Werte aus Objekten und Arrays extrahieren und Variablen auf einfache Weise zuweisen können.

Beispiel: Destrukturierung von Objekten und Arrays

const { name, age } = person;
console.log(name); // Ausgabe: "John"

const [first, second] = fruits;
console.log(second); // Ausgabe: "grape"

Klassen und Vererbung

JavaScript unterstützt objektorientierte Programmierung durch Klassen und Vererbung. Klassen sind Pläne für die Erstellung von Objekten mit bestimmten Eigenschaften und Methoden.

Um eine Klasse zu definieren, verwenden Sie das Schlüsselwort class, gefolgt vom Klassennamen. Innerhalb der Klasse können Sie eine Konstruktormethode definieren, um die Eigenschaften des Objekts zu initialisieren, sowie andere Methoden, um das Verhalten des Objekts festzulegen.

Beispiel: Definition einer Klasse

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  getArea() {
    return this.width * this.height;
  }
}

Sie können Instanzen einer Klasse mit dem Schlüsselwort new, gefolgt vom Klassennamen und allen erforderlichen Argumenten, erstellen.

Beispiel: Erstellen einer Klasseninstanz

const rect = new Rectangle(5, 3);
console.log(rect.getArea()); // Ausgabe: 15

JavaScript unterstützt auch Vererbung, mit der Sie neue Klassen basierend auf bestehenden Klassen erstellen können. Sie können das Schlüsselwort extends verwenden, um eine Unterklasse zu erstellen, die Eigenschaften und Methoden von einer Oberklasse erbt.

Beispiel: Vererbung in JavaScript

class Square extends Rectangle {
  constructor(side) {
    super(side, side);
  }
}

const square = new Square(4);
console.log(square.getArea()); // Ausgabe: 16

Unterklassen können Methoden der Oberklasse überschreiben, indem sie den gleichen Methodennamen verwenden. Sie können auch die Methode der Oberklasse mit dem Schlüsselwort super aufrufen.

Asynchrone Programmierung

JavaScript ist eine einzelsträngige Sprache, was bedeutet, dass Code sequentiell ausgeführt wird. JavaScript bietet jedoch Möglichkeiten, asynchrone Operationen wie HTTP-Anfragen oder das Lesen von Dateien zu verarbeiten, ohne die Ausführung anderen Codes zu blockieren.

In der Vergangenheit wurde asynchrone Programmierung in JavaScript mit Callbacks realisiert. Ein Callback ist eine Funktion, die als Argument an eine andere Funktion übergeben und ausgeführt wird, wenn die asynchrone Operation abgeschlossen ist.

Beispiel: Asynchrone Programmierung mit Callbacks

function fetchData(callback) {
  // Simulation einer asynchronen Operation
  setTimeout(() => {
    const data = "Hallo, Welt!";
    callback(data);
  }, 1000);
}

fetchData((data) => {
  console.log(data); // Ausgabe: "Hallo, Welt!"
});

Callbacks können jedoch zu verschachteltem und komplexem Code führen, der als "Callback-Hölle" bekannt ist. Um dieses Problem zu lösen, führte JavaScript Promises ein, die eine bessere Möglichkeit bieten, asynchrone Operationen zu verarbeiten.

Promises repräsentieren den eventuellen Abschluss oder Fehlschlag einer asynchronen Operation und ermöglichen es Ihnen, mehrere asynchrone Operationen mit den Methoden .then() und .catch() zu verketten.

Beispiel: Asynchrone Programmierung mit Promises

function fetchData() {
  return new Promise((resolve, reject) => {
    // Simulation einer asynchronen Operation
    setTimeout(() => {
      const data = "Hallo, Welt!";
      resolve(data);
    }, 1000);
  });
}

fetchData()
  .then((data) => {
    console.log(data); // Ausgabe: "Hallo, Welt!"
  })
  .catch((error) => {
    console.error(error);
  });

ES2017 führte die Schlüsselwörter async und await ein, die eine Syntax bieten, die mehr wie synchroner Code aussieht, um mit Promises zu arbeiten. Innerhalb einer async-Funktion können Sie das Schlüsselwort await verwenden, um die Ausführung zu pausieren, bis ein Promise aufgelöst ist.

Beispiel: Asynchrone Programmierung mit async/await

async function fetchData() {
  // Simulation einer asynchronen Operation
  const data = await new Promise((resolve) => {
    setTimeout(() => {
      resolve("Hallo, Welt!");
    }, 1000);
  });
  return data;
}

fetchData().then((data) => {
  console.log(data); // Ausgabe: "Hallo, Welt!"
});

JavaScripts Event-Loop und Call-Stack arbeiten zusammen, um die Ausführung von synchronem und asynchronem Code zu verwalten. Die Event-Loop überprüft ständig den Call-Stack und die Task-Queue und führt Aufgaben aus der Task-Queue aus, wenn der Call-Stack leer ist.

Fehlerbehandlung

Fehlerbehandlung ist ein wichtiger Teil beim Schreiben von robustem JavaScript-Code. JavaScript bietet die try...catch-Anweisung zur Behandlung von Ausnahmen, die während der Codeausführung auftreten können.

Sie können den Code, der möglicherweise einen Fehler verursacht, in einen try-Block einschließen und den Code zur Fehlerbehandlung im catch-Block angeben.

Beispiel: Fehlerbehandlung mit try...catch

try {
  // Code, der möglicherweise einen Fehler verursacht
  throw new Error("Etwas ist schief gelaufen!");
} catch (error) {
  console.error(error.message); // Ausgabe: "Etwas ist schief gelaufen!"
}

Sie können das Schlüsselwort throw verwenden, um eigene Fehler oder benutzerdefinierte Fehlerobjekte zu werfen. Dies ermöglicht es Ihnen, bestimmte Arten von Fehlern unterschiedlich zu behandeln.

Beispiel: Werfen benutzerdefinierter Fehler

function divide(a, b) {
  if (b === 0) {
    throw new Error("Division durch Null!");
  }
  return a / b;
}

try {
  console.log(divide(10, 0));
} catch (error) {
  console.error(error.message); // Ausgabe: "Division durch Null!"
}

ES6+ Funktionen

JavaScript hat sich im Laufe der Jahre weiterentwickelt, und ECMAScript 2015 (ES6) führte neue Funktionen ein, die in der modernen JavaScript-Entwicklung weit verbreitet sind. Diese Funktionen sollen die Sprache ausdrucksstärker, prägnanter und einfacher zu handhaben machen. Hier sind einige der bemerkenswerten ES6+ Funktionen.

Template Literals

Template Literals, auch als Template Strings bekannt, bieten eine Möglichkeit, Zeichenketten in JavaScript zu erstellen und zu bearbeiten. Sie bieten zwei wesentliche Vorteile gegenüber der traditionellen Zeichenkettenverkettung:

  1. Mehrzeilige Zeichenketten: Template Literals ermöglichen es, mehrzeilige Zeichenketten zu erstellen, ohne dass Escape-Zeichen oder Verkettung erforderlich sind. Sie können Ihren Zeichenketteninhalt in Backticks ( ) einschließen und Zeilenumbrüche direkt in die Zeichenkette einfügen.

Beispiel: Mehrzeilige Zeichenkette

const multiLineString = `
  Dies ist eine
  mehrzeilige Zeichenkette
  mit Template Literals.
`;
  1. Zeichenketteninterpolation: Template Literals unterstützen Zeichenketteninterpolation, mit der Sie Ausdrücke oder Variablen direkt in die Zeichenkette einbetten können. Indem Sie den Ausdruck oder die Variable in ${} einschließen, können Sie dynamische Werte in Ihre Zeichenketten einbinden.

Beispiel: Zeichenketteninterpolation

const name = "John";
const alter = 30;
const nachricht = `Mein Name ist ${name} und ich bin ${alter} Jahre alt.`;
console.log(nachricht); // Ausgabe: "Mein Name ist John und ich bin 30 Jahre alt."

Destrukturierende Zuweisung

Die destrukturierende Zuweisung ist eine Möglichkeit, Werte aus Objekten oder Arrays zu extrahieren und sie Variablen zuzuweisen. Sie bietet eine prägnante Syntax zum Auspacken von Werten aus Datenstrukturen.

  1. Objekt-Destrukturierung: Die Objekt-Destrukturierung ermöglicht es, bestimmte Eigenschaften aus einem Objekt zu extrahieren und sie Variablen mit entsprechendem Namen zuzuweisen.

Beispiel: Objekt-Destrukturierung

const person = {
  name: "John",
  alter: 30,
  stadt: "New York"
};

const { name, alter } = person;
console.log(name); // Ausgabe: "John"
console.log(alter); // Ausgabe: 30
  1. Array-Destrukturierung: Die Array-Destrukturierung ermöglicht es, Werte aus einem Array basierend auf ihrer Position zu extrahieren und sie Variablen zuzuweisen.

Beispiel: Array-Destrukturierung

const zahlen = [1, 2, 3, 4, 5];
const [a, b, ...rest] = zahlen;
console.log(a); // Ausgabe: 1
console.log(b); // Ausgabe: 2
console.log(rest); // Ausgabe: [3, 4, 5]

Die destrukturierende Zuweisung unterstützt auch Standardwerte, die verwendet werden, wenn der extrahierte Wert undefined ist, und ermöglicht es, Variablen während des Zuweisungsprozesses umzubenennen.

Pfeilfunktionen

Pfeilfunktionen bieten eine prägnante Syntax zur Definition von Funktionen in JavaScript. Sie bieten eine kompakte Alternative zu traditionellen Funktionsausdrücken.

  1. Prägnante Syntax: Pfeilfunktionen eliminieren die Notwendigkeit des function-Schlüsselworts und verwenden die =>-Syntax zur Definition der Funktion.

Beispiel: Pfeilfunktion - Prägnante Syntax

const grüßen = (name) => {
  return `Hallo, ${name}!`;
};
console.log(grüßen("John")); // Ausgabe: "Hallo, John!"

Wenn der Funktionskörper aus einem einzelnen Ausdruck besteht, können Sie die geschweiften Klammern und das return-Schlüsselwort weglassen, was die Syntax noch prägnanter macht.

Beispiel: Pfeilfunktion - Einzelner Ausdruck

const quadrat = (x) => x * x;
console.log(quadrat(5)); // Ausgabe: 25
  1. Lexikalische this-Bindung: Pfeilfunktionen haben eine lexikalische this-Bindung, was bedeutet, dass sie den this-Wert aus dem umgebenden Bereich erben. Dieses Verhalten ist nützlich bei der Arbeit mit Objektmethoden oder Callback-Funktionen.

Beispiel: Pfeilfunktion - Lexikalische 'this'-Bindung

const person = {
  name: "John",
  grüßen: function() {
    setTimeout(() => {
      console.log(`Hallo, ${this.name}!`);
    }, 1000);
  }
};
person.grüßen(); // Ausgabe: "Hallo, John!" (nach 1 Sekunde)

Module

ES6 führte ein standardisiertes Modulsystem für JavaScript ein, das es ermöglicht, Ihren Code in wiederverwendbare und gekapselte Module zu organisieren. Module bieten eine Möglichkeit, Code über verschiedene Dateien oder Projekte hinweg zu definieren und zu teilen.

  1. Module exportieren: Um einen Wert, eine Funktion oder eine Klasse für die Verwendung in anderen Modulen verfügbar zu machen, müssen Sie sie mit dem export-Schlüsselwort exportieren.

Beispiel: Module exportieren

// math.js
export function addieren(a, b) {
  return a + b;
}

export const PI = 3.14159;
  1. Module importieren: Um Werte, Funktionen oder Klassen aus einem anderen Modul zu verwenden, müssen Sie sie mit dem import-Schlüsselwort importieren.

Beispiel: Module importieren

// main.js
import { addieren, PI } from './math.js';

console.log(addieren(2, 3)); // Ausgabe: 5
console.log(PI); // Ausgabe: 3.14159

Module unterstützen auch Standard-Exporte, die es ermöglichen, einen einzelnen Wert als Standard-Export eines Moduls zu exportieren, und benannte Exporte, die es ermöglichen, mehrere benannte Werte aus einem Modul zu exportieren.

Rest- und Spread-Operatoren

Die Rest- und Spread-Operatoren (...) bieten eine Möglichkeit, mit mehreren Elementen auf prägnante Weise zu arbeiten.

  1. Rest-Parameter: Der Rest-Operator ermöglicht es, mehrere an eine Funktion übergebene Argumente als Array zu erfassen.

Beispiel: Rest-Parameter

function summe(...zahlen) {
  return zahlen.reduce((acc, curr) => acc + curr, 0);
}
console.log(summe(1, 2, 3, 4, 5)); // Ausgabe: 15
  1. Spread-Operator: Der Spread-Operator ermöglicht es, die Elemente eines Arrays oder Objekts in ein anderes Array oder Objekt zu verteilen.

Beispiel: Spread-Operator

const zahlen = [1, 2, 3];
const neueZahlen = [...zahlen, 4, 5];
console.log(neueZahlen); // Ausgabe: [1, 2, 3, 4, 5]

const person = { name: "John", alter: 30 };
const neuePerson = { ...person, stadt: "New York" };
console.log(neuePerson); // Ausgabe: { name: "John", alter: 30, stadt: "New York" }

Dies sind einige der bemerkenswerten ES6+ Funktionen, die in JavaScript eingeführt wurden. Weitere Funktionen umfassen Standard-Funktionsparameter, erweiterte Objekt-Literale, Klassen, Promises und mehr. Diese Funktionen haben die Ausdruckskraft, Lesbarkeit und Funktionalität der Sprache erheblich verbessert und machen die JavaScript-Entwicklung angenehmer und effizienter.