ProgrammierungFrontend-Entwickler

Wie funktionieren die Zugriffsmodifizierer (public, private, protected) in TypeScript? Welche Nuancen gibt es bei deren Verwendung mit Vererbung und bei der Transpilation von Code nach JavaScript?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort

In TypeScript werden Zugriffsmodifizierer verwendet, um den Sichtbarkeitsbereich von Eigenschaften und Methoden in Klassen einzuschränken:

  • public — die Eigenschaft oder Methode ist überall zugänglich (Standard).
  • private — nur im Klassenkontext, in dem sie deklariert sind, zugänglich.
  • protected — zugänglich in der Klasse und ihren Erben.
class Animal { public name: string; private age: number; protected kind: string; constructor(name: string, age: number, kind: string) { this.name = name; this.age = age; this.kind = kind; } } class Dog extends Animal { bark() { console.log(this.kind); // OK: protected // console.log(this.age); // Fehler: private ist im Erben nicht sichtbar } } const dog = new Dog('Bello', 5, 'Säugetier'); console.log(dog.name); // OK // console.log(dog.kind); // Fehler: protected // console.log(dog.age); // Fehler: private

Nuancen:

  • Im kompilierten JavaScript werden die Modifizierer private und protected nur zur Kompilierungszeit implementiert, es gibt keine physische Isolation zur Laufzeit! Der JS-Code enthält alle Eigenschaften (diese können beispielsweise durch Durchlaufen des Objekts abgerufen werden).
  • In neueren Versionen (ab TypeScript 3.8) wurde eine Syntax für echte private Felder eingeführt: #field, aber das ist bereits eine JS-Spezifikation und wird anders kompiliert.

Fangfrage

Frage: Kann man nach der Kompilierung in JavaScript auf eine private Eigenschaft einer TypeScript-Klasse zugreifen?

Antwort: Ja, da private (und protected) eine Typüberprüfung von TypeScript zur Kompilierungszeit sind, bleibt die Privatsphäre nach der Kompilierung in ES5 oder ES6 nicht erhalten, die Eigenschaften bleiben im Objekt und sind durch den Zugriff auf den Eigenschaftsnamen verfügbar (zum Beispiel über object['privateProp']).

// JS-Code nach der Kompilierung function Animal(name, age, kind) { this.name = name; this.age = age; this.kind = kind; } var dog = new Animal('Bello', 5, 'Säugetier'); console.log(dog['age']); // 5 — kein Zugriff nur auf TS-Ebene!

Beispiele für reale Fehler aufgrund mangelnden Wissens über die Feinheiten des Themas.


Geschichte

In einem großen Projekt ging der Entwickler von der Annahme aus, dass private Felder zur Laufzeit nicht zugänglich sind. Dadurch gelangten vertrauliche Daten während der Objektspeicherung durch Serialisierung (JSON.stringify) in die Protokolle, da die TS-Typisierung nicht vor dem tatsächlichen Zugriff auf die Felder schützte.


Geschichte

In einem Projekt wurde ein Mechanismus zur "Erweiterung" von Klasseninstanzen durch dynamisches Hinzufügen von Eigenschaften implementiert. Die dynamisch hinzugefügten Eigenschaften überschrieben private Namen und wurden versehentlich durch äußeren Code verändert. Der Fehler wurde erst in der Produktion entdeckt, wobei die Privatsphäre nicht gewährleistet war.


Geschichte

Bei der Migration von JavaScript zu TypeScript begann das Team, protected zu verwenden, in der Annahme, dass dies vor der Nutzung von Feldern außerhalb von Unterklassen schützt. Aber der Programmierer hat versehentlich das protected-Feld zur Laufzeit mit Object.assign überschrieben und einen schwer zu diagnostizierenden Fehler erhalten. Dies wurde möglich, weil es keine Laufzeitkapselung gab.