Veränderlich und Unveränderlich in TypeScript

Veränderlich und Unveränderlich in TypeScript

Dieser Artikel erklärt die Konzepte von Veränderlichkeit und Unveränderlichkeit in TypeScript.

YouTube Video

Veränderlich und Unveränderlich in TypeScript

Was bedeutet Veränderlich?

Veränderlich bedeutet, dass ein Wert geändert werden kann. Referenztypen wie Objekte und Arrays sind typische Beispiele für veränderliche Datenstrukturen.

Beispiel für ein veränderliches Objekt

1type Person = { name: string; age: number };
2
3// Mutable Example: Object
4let person: Person = { name: "Alice", age: 25 };
5person.age = 26;
6console.log(person); // { name: "Alice", age: 26 }

In diesem Code wird die age-Eigenschaft des person-Objekts von 25 auf 26 geändert. Da Objekte per Referenz übergeben werden, werden die Inhalte an der Speicheradresse, die in der Variablen person gespeichert ist, geändert.

Beispiel für ein veränderliches Array

1// Mutable Example: Array
2let numbers: number[] = [1, 2, 3];
3numbers.push(4);
4console.log(numbers); // [1, 2, 3, 4]

In diesem Code wird die push-Methode verwendet, um ein neues Element 4 zum ursprünglichen Array hinzuzufügen. Dies modifiziert das ursprüngliche Array und macht es zu einer veränderlichen Operation.

Beispiel in einer Funktion

1// Mutable Example: Function
2function append(arr: number[], value: number): void {
3    arr.push(value); // Modify the original array
4    console.log(arr);
5}
6
7let nums: number[] = [1, 2, 3];
8append(nums, 4);
9console.log(nums); // [1, 2, 3, 4]

Wenn in einer Funktion veränderliche Operationen durchgeführt werden, wird auch das ursprüngliche Array modifiziert.

Was bedeutet Unveränderlich?

Unveränderlich bedeutet, dass ein Wert nicht geändert werden kann. Primitive Datentypen sind grundsätzlich unveränderlich.

Beispiel für einen unveränderlichen primitiven Datentyp

1// Immutable Example: String
2let str: string = "hello";
3str[0] = "H"; // Error: Index assignment is not allowed
4console.log(str); // "hello"

Der Versuch, das erste Zeichen des Strings str in H zu ändern, schlägt fehl, da Strings unveränderlich sind.

Beispiel in einer Funktion

1// Immutable Example: Function
2function increment(num: number): number {
3    num++; // This modifies only the local copy of num
4    return num;
5}
6
7let number: number = 10;
8console.log(increment(number)); // 11
9console.log(number); // 10 (original number remains unchanged)

Da Zahlen unveränderlich sind, beeinflussen Operationen innerhalb einer Funktion die ursprüngliche Variable nicht.

Unveränderliche Operationen an Arrays

Arrays sind veränderlich, aber durch das Erstellen eines neuen Arrays anstelle der Modifikation des ursprünglichen Arrays können unveränderliche Operationen durchgeführt werden.

1// Create an array of numbers
2let numbers: number[] = [1, 2, 3];
3
4// Immutable Example: Creating a new array
5let newNumbers: number[] = [...numbers, 4];
6
7console.log(numbers); // [1, 2, 3] (original array is unchanged)
8console.log(newNumbers); // [1, 2, 3, 4] (new array with an added element)

Hier wird die Spread-Syntax (...) verwendet, um ein neues Array newNumbers zu erstellen. Da das ursprüngliche Array numbers unverändert bleibt, handelt es sich hierbei um eine unveränderliche Operation.

Vorteile der Verwendung unveränderlicher Datenstrukturen

Verbesserte Vorhersehbarkeit

Unveränderliche Daten ändern sich nicht, was unerwartete Änderungen unwahrscheinlicher macht und die Wahrscheinlichkeit von Fehlern verringert.

Kompatibilität mit auf Unveränderlichkeit basierenden Bibliotheken

Bibliotheken wie React und Redux basieren oft auf unveränderlichen Daten, was die Zustandsverwaltung bei angemessener Verwendung erleichtert.

Objekte mit Object.freeze unveränderlich machen

Object.freeze kann verwendet werden, um Änderungen an einem Objekt zu verhindern.

1// Create a frozen object (properties cannot be modified)
2const person = Object.freeze({ name: "Alice", age: 25 });
3
4// Attempt to modify a property (ignored in non-strict mode, error in strict mode)
5person.age = 26;
6
7console.log(person); // { name: "Alice", age: 25 }

Allerdings führt Object.freeze nur eine flache Einfrieren durch, das bedeutet, dass Eigenschaften verschachtelter Objekte weiterhin veränderlich bleiben.

1// Create a frozen object with a nested object
2const user: Readonly<{ profile: { name: string } }> = Object.freeze({
3    profile: { name: "Bob" }
4});
5
6// Attempt to modify a nested property (this works because Object.freeze() is shallow)
7user.profile.name = "Charlie"; // No TypeScript error, but still mutable
8
9console.log(user.profile.name); // "Charlie" (nested object is still mutable)

Um ein vollständig unveränderliches Objekt zu erstellen, ist ein tiefes Einfrieren erforderlich.

 1// Function to deeply freeze an object, making all nested objects immutable
 2function deepFreeze<T>(obj: T): Readonly<T> {
 3    Object.freeze(obj);
 4    Object.getOwnPropertyNames(obj).forEach(prop => {
 5        const value = (obj as any)[prop];
 6        if (typeof value === "object" && value !== null) {
 7            deepFreeze(value);
 8        }
 9    });
10    return obj;
11}
12
13// Create a deeply frozen object
14const user = deepFreeze({
15  profile: { name: "Bob" }
16});
17
18// Attempt to modify a nested property
19// (this will now throw an error in strict mode)
20user.profile.name = "Charlie";  // No TypeScript error, but modification is not allowed at runtime
21
22console.log(user.profile.name); // "Bob" (unchanged due to deep freeze)

Zusammenfassung

  • Veränderliche Daten sind modifizierbar und umfassen Objekte und Arrays.
  • Unveränderliche Daten sind nicht modifizierbar und umfassen primitive Datentypen wie Strings und Zahlen.
  • Mit der Spread-Syntax oder Methoden wie map können Operationen mit unveränderlichen Daten durchgeführt werden.
  • Object.freeze und deepFreeze können verwendet werden, um Änderungen an Objekten zu verhindern.
  • Die Verwendung unveränderlicher Daten hilft, vorhersagbareren und weniger fehleranfälligen Code zu schreiben.

Ein unveränderliches Design verbessert die Codesicherheit und Lesbarkeit, also nutzen Sie es voll aus!

Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.

YouTube Video