JavaScript-Methoden für primitive Typen
Wie JavaScript-Primitive wie strings, Zahlen, boolean, Symbole und BigInts Methoden über temporäre Objekt-Wrapper aufrufen können – mit Beispielen und häufigen Fallstricken.
Einführung in JavaScript-Primitive und Objekte
In JavaScript besteht nahezu alles, was man schreibt, entweder aus einem Primitiv oder einem object. Den Unterschied zu verstehen – und den cleveren Trick, der Primitiven ein objektähnliches Verhalten ermöglicht – ist eine der Grundlagen der Sprache.
Ein Primitiv ist der einfachste, unteilbare Wertetyp. Es gibt sieben primitive Typen: Zahlen, strings, boolean, undefined, null, Symbole und BigInts. Ein object ist eine Sammlung von Eigenschaften und Methoden.
Hier ist das Rätsel, das diese Seite löst: Ein string ist ein Primitiv ohne eigene Methoden, doch "hello".toUpperCase() funktioniert. Wie kann ein Wert ohne Methoden eine Methode aufrufen? Die Antwort sind Objekt-Wrapper, und dieses Kapitel erklärt genau, wie sie funktionieren.
Diese Seite behandelt, was Primitive besonders macht, wie JavaScript sie kurzzeitig einhüllt, damit Methoden aufgerufen werden können, welche Methoden für jeden primitiven Typ verfügbar sind und den häufigen Fehler, new mit einem primitiven Konstruktor zu verwenden.
Was macht Primitive besonders
Primitive unterscheiden sich von Objekten in drei wichtigen Punkten.
1. Unveränderlichkeit. Sobald ein primitiver Wert erstellt wurde, kann er nicht mehr geändert werden. Eine string-Operation bearbeitet den ursprünglichen string niemals direkt – sie gibt einen brandneuen string zurück. Der Versuch, einem Zeichen zuzuweisen, hat keinen Effekt (und wirft im Strict Mode einen Fehler):
2. Speicherung als Wert. Ein Primitiv wird direkt in der Variable gespeichert. Wenn man es kopiert, kopiert man den Wert selbst, sodass die beiden Variablen völlig unabhängig sind:
Objekte hingegen werden als Referenz gespeichert – das Kopieren der Variable kopiert nur einen Zeiger auf dasselbe object.
3. Einfach und leichtgewichtig. Ein Primitiv trägt keine eigenen Eigenschaften oder Methoden, was es schnell erstellen und vergleichen lässt. Ein boolean wie let flag = true; ist nur ein Wert, ohne den Overhead, den ein object mitbringen würde.
Objekte in JavaScript: Ein Vergleich
Objekte sind die komplexere Struktur. Im Gegensatz zu Primitiven sind sie:
- Veränderlich – ihr Inhalt kann nach der Erstellung geändert werden.
- Referenztypen – objects werden als Referenz gespeichert und kopiert, nicht als Wert.
- Vielseitig – sie können Funktionen, arrays und andere Objekte enthalten.
Wie Primitive Methoden aufrufen: Objekt-Wrapper
Wie funktioniert "hello".toUpperCase(), wenn der string keine Methoden hat? Wenn man auf eine Eigenschaft oder Methode eines Primitivs zugreift, geht JavaScript folgendermaßen vor:
- Es erstellt ein temporäres Wrapper-object des passenden Typs, das den primitiven Wert enthält.
- Es liest die angeforderte Methode oder Eigenschaft aus diesem Wrapper.
- Es führt sie aus und gibt das Ergebnis zurück.
- Es verwirft das Wrapper-object sofort.
Dieser gesamte Vorgang findet hinter den Kulissen statt und wird von der Engine stark optimiert, sodass er praktisch kostenfrei ist. Die wichtigste Erkenntnis: Das Primitiv selbst wird niemals verändert und wird nie dauerhaft zu einem object – der Wrapper existiert nur für die Dauer dieses einzelnen Ausdrucks.
Die Wrapper-Konstruktoren
Fünf primitive Typen verfügen über einen entsprechenden eingebauten Wrapper-Konstruktor, der ihre Methoden bereitstellt:
- String – für string-Primitive.
- Number – für numerische Werte.
- Boolean – für boolean-Werte.
- Symbol – für Symbole.
- BigInt – für BigInts.
null und undefined haben keinen Wrapper, daher wirft das Lesen einer Eigenschaft auf ihnen einen TypeError (zum Beispiel schlägt null.toString() fehl).
String-Methoden
Strings stellen über den String-Wrapper eine umfangreiche Sammlung von Methoden bereit. Hier kombinieren sich einige davon, um einen Satz in Titelschreibweise umzuwandeln:
Zu beachten ist, dass length eine Eigenschaft und keine Methode ist, weshalb sie keine Klammern hat. toUpperCase() gibt einen neuen string zurück und lässt greeting unverändert, getreu der oben beschriebenen Unveränderlichkeitsregel.
Number-Methoden
Zahlen erhalten Methoden über den Number-Wrapper. Eine häufig verwendete Methode ist toFixed(), die auf eine feste Anzahl von Dezimalstellen rundet:
Zwei Dinge sind zu beachten. Erstens gibt toFixed() einen string zurück, keine Zahl – typeof (3.14159).toFixed(2) ergibt "string". Zweitens benötigt man zum direkten Aufrufen einer Methode auf einem Zahlen-Literal zusätzliche Klammern oder ein Leerzeichen: 255..toString(16) funktioniert ebenfalls, aber 255.toString(16) ist ein Syntaxfehler, weil der Parser den ersten Punkt als Dezimalpunkt interpretiert.
Boolean-Methoden
Booleans können den Boolean-Wrapper nutzen, meistens nur toString():
Symbol-Methoden
Symbole, ein einzigartiger primitiver Typ, erhalten Methoden über den Symbol-Wrapper:
toString() muss hier explizit aufgerufen werden – Symbole konvertieren absichtlich nicht automatisch zu einem string in string-Kontexten (wie "" + sym), was sonst einen TypeError werfen würde.
BigInt-Methoden
BigInt, konzipiert für Ganzzahlen, die zu groß für den regulären Number-Typ sind, erhält Methoden über den BigInt-Wrapper:
Der Wert wird hier als string übergeben, weil das Schreiben als numerisches Literal den sicheren Ganzzahlbereich überschreiten und Genauigkeit verlieren würde, bevor BigInt ihn überhaupt verarbeitet.
Der Fallstrick: new niemals mit primitiven Wrappern verwenden
JavaScript erlaubt es, ein Wrapper-object selbst mit new Number(1), new String("x") oder new Boolean(false) zu erstellen – aber das sollte man so gut wie nie tun. Ein mit new erstellter Wrapper ist ein echtes object, und jedes object ist truthy, einschließlich eines, das false einhüllt:
Dies ist eine klassische Fehlerquelle. Den Konstruktor ohne new aufzurufen ist hingegen in Ordnung und nützlich – Number("42"), String(123) und Boolean(value) führen eine einfache Typkonvertierung durch und geben Primitive zurück, keine Objekte.
Zusammenfassung
- Primitive sind einfache, unveränderliche Werte, die als Wert gespeichert werden; Objekte sind veränderlich und werden als Referenz gespeichert.
- Das Aufrufen einer Methode auf einem Primitiv funktioniert, weil JavaScript es in ein temporäres object einhüllt, die Methode ausführt und den Wrapper anschließend verwirft.
String,Number,Boolean,SymbolundBigIntstellen die Methoden bereit;nullundundefinedhaben keinen Wrapper und werfen einen Fehler, wenn man auf eine Eigenschaft zugreift.- Wrapper-Funktionen ohne
newfür die Typkonvertierung verwenden. Niemalsnewnutzen, um Wrapper-Objekte im alltäglichen Code zu erstellen – sie sind immer truthy und verhalten sich unerwartet.
Als Nächstes die Methoden der einzelnen Typen im Detail erkunden: strings, Zahlen und BigInt.