Sieben primitive Typen – und alles andere
JavaScript teilt Werte in zwei Lager ein. Auf der einen Seite stehen die sieben primitiven Datentypen – einfache, unveränderliche Werte. Auf der anderen Seite die Objekte – alles, was zusammengesetzt, veränderbar oder aufrufbar ist. Mehr gibt das Typsystem auf Werteebene nicht her.
Die sieben primitiven Typen in JavaScript:
Alles, was nicht in dieser Liste steht — Arrays, Funktionen, Dates, RegExes, schlichte {} — ist ein Objekt. Mit typeof bekommst du den Typ zur Laufzeit, und in der letzten Zeile fällt dir bestimmt der berühmte Schönheitsfehler auf: typeof null liefert seit 1995 'object' zurück, und das wird sich auch nie ändern — zu viel bestehender Code verlässt sich darauf.
Ein primitiver Wert ist ein Wert, keine Hülle
Folgendes Modell hilft am meisten weiter: Ein primitiver Wert ist sein Wert. Die Zahl 3 ist keine Box, in der eine 3 liegt — sie ist einfach 3. Zwei Variablen, die 3 enthalten, halten denselben Wert, nicht zwei Kopien, die auf irgendetwas Gemeinsames zeigen:
Primitive Werte werden über den Wert verglichen, Objekte über ihre Referenz. Dieser kleine, aber feine Unterschied steckt hinter vielen späteren "Warum ist das hier false?"-Momenten – gerade wenn man Arrays oder Objekte mit === vergleicht.
Primitive Typen sind unveränderlich (immutable)
Einen primitiven Wert kannst du nicht verändern. Jede Operation, die nach einer Mutation aussieht, erzeugt in Wirklichkeit einen neuen Wert:
Der erste Aufruf erzeugt einen neuen String und wirft ihn direkt weg, weil niemand den Rückgabewert auffängt. Der zweite weist name neu zu. Das ursprüngliche "ada" wurde nie verändert – kann es gar nicht. Bei Zahlen läuft es genauso: x + 1 liefert eine neue Zahl, es verändert x nicht.
Genau deshalb ist const bei Strings oder Zahlen auch wirklich sicher. Der Wert selbst kann sich nicht ändern, und const verhindert, dass du die Variable neu zuweist.
Number und BigInt – warum es zwei Zahlentypen gibt
In JavaScript ist number ein 64-Bit-Float. Das bedeutet: schnelle Arithmetik, aber eine Obergrenze – ganze Zahlen sind nur bis Number.MAX_SAFE_INTEGER (2^53 - 1) exakt darstellbar:
Jenseits dieser Grenze fangen Ganzzahlen an, sich zu überschneiden. Genau für Fälle, in denen Integer bei beliebiger Größe exakt bleiben müssen, gibt es bigint. Geschrieben wird so ein Wert mit dem Suffix n:
bigint und number lassen sich in arithmetischen Operationen nicht mischen – sonst wäre die höhere Genauigkeit ja für die Katz. Greif zu bigint, wenn du mit Datenbank-IDs, Nanosekunden-Timestamps oder Krypto arbeitest. Alles andere bleibt bei number.
Auch Strings sind primitive Datentypen
Ein String ist in JavaScript ein primitiver Typ, kein Objekt – und das, obwohl er Methoden wie .length, .slice oder .toUpperCase anbietet:
Wenn du eine Methode auf einem String aufrufst, packt JavaScript den String im Hintergrund kurz in ein String-Objekt, damit der Methodenaufruf funktioniert, und wirft diesen Wrapper gleich danach wieder weg. Um diesen Wrapper musst du dich nicht kümmern — wichtig ist nur, dass sich Strings wie Werte verhalten (immutable, Vergleich per Wert), auch wenn sie jede Menge Methoden mitbringen.
Einfache Anführungszeichen, doppelte Anführungszeichen und Backticks erzeugen alle denselben Typ. Backticks können zusätzlich Interpolation und mehrzeilige Strings — darum geht es im nächsten Abschnitt.
null vs. undefined in JavaScript
Es gibt zwei primitive Typen, die „kein Wert" bedeuten, und austauschbar sind sie nicht.
undefined bekommst du immer dann, wenn etwas nie zugewiesen wurde — eine deklarierte, aber nicht gesetzte Variable, ein fehlendes Funktionsargument oder eine Eigenschaft, die gar nicht existiert:
null schreibst du selbst, wenn du ausdrücken willst: "bewusst leer":
Die gängige Konvention: undefined ist die Art der Sprache zu sagen "hier ist nichts", null ist die Art des Entwicklers. Beide sind falsy, beide schlagen beim Vergleich mit normalen Werten fehl – und beide bekommen später eine eigene Seite.
Symbols: Einzigartig per Konstruktion
Der Datentyp symbol ist der am seltensten genutzte primitive Typ in JavaScript. Jedes Symbol, das du erzeugst, ist einzigartig – selbst dann, wenn zwei Symbole aus derselben Beschreibung gebaut werden:
Symbole eignen sich hervorragend als Schlüssel für Objekte, wenn man Kollisionen mit bestehenden Keys ausschließen will — eine Library kann Metadaten an deine Objekte hängen und sich darauf verlassen, dass kein anderer Code sie überschreibt. Wieder begegnen wirst du ihnen bei Iteratoren und sogenannten Well-known Symbols wie Symbol.iterator.
Typen zur Laufzeit prüfen mit typeof
Für die meisten Fälle reicht typeof völlig aus. Ein paar Eigenheiten solltest du aber im Hinterkopf behalten:
Für null vergleichst du direkt: value === null. Bei Arrays nimmst du Array.isArray(value). Für die Frage „Ist das überhaupt ein primitiver Typ?" gibt es zwar keine eingebaute Funktion, aber das gängige Idiom ist klar genug:
Primitive vs. Objekt: die Stolperfalle bei der Zuweisung
Bevor wir weitermachen, lohnt sich noch ein Blick auf einen Punkt, der viele am Anfang auf dem falschen Fuß erwischt. Weil primitive Datentypen in JavaScript als Wert übergeben werden und Objekte als Referenz, verhält sich eine Zuweisung in beiden Fällen unterschiedlich:
Bei primitiven Werten kopiert b = a den Wert. Bei Objekten kopiert y = x dagegen die Referenz – beide Namen zeigen auf dasselbe Objekt dahinter. Änderst du über den einen Namen etwas, siehst du das auch über den anderen. Genau daraus entstehen in JavaScript die meisten "Moment mal, warum hat sich das jetzt geändert?"-Bugs.
Das Wichtigste zum Mitnehmen
- Sieben primitive Datentypen in JavaScript:
string,number,bigint,boolean,null,undefined,symbol. Alles andere ist ein Objekt. - Primitive Typen sind unveränderlich und werden nach Wert verglichen; Objekte sind veränderbar und werden nach Referenz verglichen.
typeofverrät dir den Typ zur Laufzeit – mit zwei Eigenheiten, die du dir merken solltest:typeof null === "object"undtypeof function(){} // "function".numberist ein 64-Bit-Float mit einer Obergrenze für sicher darstellbare Ganzzahlen; für exakte Ganzzahlen jenseits dieser Grenze gibt esbigint.
Als Nächstes: Strings und Template Literals
Strings sind der primitive Typ, mit dem du am häufigsten zu tun hast. Template Literals (also die Strings mit Backticks) machen dir das Leben dabei deutlich leichter – Interpolation, mehrzeilige Texte, Tagged Templates inklusive. Darum geht es auf der nächsten Seite.
Häufig gestellte Fragen
Wie viele primitive Datentypen hat JavaScript?
Sieben Stück: string, number, bigint, boolean, null, undefined und symbol. Alles andere — Arrays, Funktionen, Dates, normale Objekte — sind Objekte. Den Typ eines Werts kannst du zur Laufzeit mit typeof prüfen, wobei eine historische Macke geblieben ist: typeof null liefert 'object'.
Was ist der Unterschied zwischen Primitiven und Objekten in JavaScript?
Primitive sind unveränderlich und werden über ihren Wert verglichen — zwei 3en sind einfach dieselbe 3. Objekte dagegen sind veränderbar und werden per Referenz verglichen — zwei {} sind verschieden, auch wenn sie gleich aussehen. Beim Zuweisen eines Primitiven wird der Wert kopiert, bei einem Objekt nur die Referenz auf dieselben Daten.
Sind Primitive in JavaScript wirklich unveränderlich?
Ja. Du kannst ein Primitive nicht in-place verändern — 'hello'.toUpperCase() gibt einen neuen String zurück und lässt das Original unangetastet. Wenn du eine Variable neu zuweist (x = x + 1), bekommt sie einfach einen anderen Primitiven zugewiesen; der ursprüngliche Wert selbst ändert sich nie. Genau deshalb kannst du bei const name = 'Ada' trotzdem problemlos neue Strings aus name bauen.
Warum gibt typeof null den Wert 'object' zurück?
Das ist ein Bug aus der Ur-Implementierung von 1995, der nie gefixt wurde, weil schlicht zu viel Code darauf aufgebaut hat. Um auf null zu prüfen, nimmst du ===: value === null. Für undefined funktioniert entsprechend value === undefined oder typeof value === 'undefined'.