Veranderlijk en Onveranderlijk in TypeScript
Dit artikel legt de concepten van veranderlijk en onveranderlijk uit in TypeScript.
YouTube Video
Veranderlijk en Onveranderlijk in TypeScript
Wat is Veranderlijk?
Veranderlijk betekent dat een waarde kan worden gewijzigd. Referentietypen zoals objecten en arrays zijn typische voorbeelden van veranderlijke datastructuren.
Voorbeeld van een Veranderlijk Object
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 deze code wordt de age
-eigenschap van het person
-object gewijzigd van 25
naar 26
. Omdat objecten via referentie worden doorgegeven, worden de inhoud op het geheugenadres in de person
-variabele aangepast.
Voorbeeld van een Veranderlijke Array
1// Mutable Example: Array
2let numbers: number[] = [1, 2, 3];
3numbers.push(4);
4console.log(numbers); // [1, 2, 3, 4]
In deze code wordt de push
-methode gebruikt om een nieuw element 4
aan de originele array toe te voegen. Hiermee wordt de originele array aangepast, wat het een veranderlijke bewerking maakt.
Voorbeeld in een Functie
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]
Bij het uitvoeren van veranderlijke bewerkingen binnen een functie wordt ook de originele array aangepast.
Wat is Onveranderlijk?
Onveranderlijk betekent dat een waarde niet kan worden gewijzigd. Primitieve typen zijn fundamenteel onveranderlijk.
Voorbeeld van een Onveranderlijk Primitief Type
1// Immutable Example: String
2let str: string = "hello";
3str[0] = "H"; // Error: Index assignment is not allowed
4console.log(str); // "hello"
Pogingen om het eerste teken van de string str
te wijzigen in H
mislukken omdat strings onveranderlijk zijn.
Voorbeeld in een Functie
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)
Omdat getallen onveranderlijk zijn, hebben bewerkingen binnen een functie geen invloed op de originele variabele.
Onveranderlijke Bewerking op Arrays
Arrays zijn veranderlijk, maar door een nieuwe array te maken in plaats van de originele te wijzigen, kunnen onveranderlijke bewerkingen worden bereikt.
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 wordt de spreadsynthax (...
) gebruikt om een nieuwe array newNumbers
te maken. Omdat de originele numbers
-array onveranderd blijft, is dit een onomkeerbare operatie.
Voordelen van het Gebruiken van Onveranderlijke Datastructuren
Verbeterde Voorspelbaarheid
Onveranderlijke gegevens veranderen niet, waardoor onverwachte aanpassingen minder waarschijnlijk zijn en de kans op fouten wordt verkleind.
Compatibiliteit met Bibliotheken Gebaseerd op Onveranderlijke Gegevens
Bibliotheken zoals React
en Redux
zijn vaak ontworpen op basis van onveranderlijke gegevens, wat het beheer van de toestand eenvoudiger maakt wanneer ze op de juiste manier worden gebruikt.
Objecten Onveranderlijk Maken met Object.freeze
Object.freeze
kan worden gebruikt om aanpassingen aan een object te voorkomen.
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 }
Echter, Object.freeze
voert alleen een oppervlakkige bevriezing uit, wat betekent dat eigenschappen van geneste objecten nog steeds aanpasbaar blijven.
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)
Om een volledig onveranderlijk object te maken, is een diepe bevriezing vereist.
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)
Samenvatting
- Veranderlijke gegevens zijn aanpasbaar en omvatten objecten en arrays.
- Onveranderlijke gegevens zijn niet aanpasbaar en omvatten primitieve typen zoals strings en nummers.
- Met behulp van spreadsynthax of methoden zoals
map
kunnen operaties op onveranderlijke gegevens worden uitgevoerd. Object.freeze
endeepFreeze
kunnen worden gebruikt om aanpassingen aan objecten te voorkomen.- Het gebruik van onveranderlijke gegevens helpt om meer voorspelbare en minder foutgevoelige code te schrijven.
Het toepassen van een onveranderlijk ontwerp verbetert de veiligheid en leesbaarheid van code, dus maak er volop gebruik van!
Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.