Start · Sprachen · JavaScript · Referenz · Objekt-Initialisierer

Objekt-Initialisierer

Keyword

Der Objekt-Initialisierer (Objektliteral) <code>{ … }</code> erzeugt ein neues Objekt aus einer durch Kommata getrennten Liste von Eigenschaftsnamen und Werten.

seit JavaScript ES1 (Kurzschreibweisen und berechnete Schlüssel: E Kategorie: syntax

Signatur

const obj = { key1: value1, key2, [computedKey]: value3, method() {}, get prop() {}, set prop(v) {}, ...source }

Beschreibung

Ein Objekt-Initialisierer, meist Objektliteral genannt, ist die kürzeste und gebräuchlichste Art, in JavaScript ein Objekt anzulegen. Zwischen geschweiften Klammern {} stehen null oder mehr Paare aus Eigenschaftsname und Wert, getrennt durch Kommata. Jede Auswertung des Ausdrucks erzeugt ein neues Objekt mit Object.prototype als Prototyp. Ein leeres Literal {} entspricht also im Wesentlichen new Object().

Seit ES2015 bzw. ES2018 gibt es mehrere Kurzschreibweisen:

  • Eigenschafts-Kurzform: { name } statt { name: name }
  • Methoden-Kurzform: { greet() {} } statt { greet: function () {} }, dabei ist super nutzbar
  • Berechnete Eigenschaftsnamen: { [`id_${n}`]: wert }
  • Getter und Setter: get und set für Zugriffseigenschaften
  • Spread-Eigenschaften: { ...quelle } kopiert die eigenen, aufzählbaren Eigenschaften (flache Kopie)
  • Prototyp setzen: { __proto__: proto } legt den Prototyp des neuen Objekts fest

Du nutzt Objektliterale für Konfigurationsobjekte, Rückgabewerte mit mehreren Feldern, Datenstrukturen wie JSON-ähnliche Datensätze, benannte Funktionsparameter und unveränderliche Aktualisierungen (etwa im State-Management mit { ...state, key: neu }).

Eigenschaftsnamen sind immer Strings oder Symbole. Zahlen und andere Werte werden in Strings umgewandelt. Kommt ein Schlüssel mehrfach vor, gewinnt der zuletzt angegebene Wert.

Parameter

Name Typ Default Beschreibung
$key Bezeichner | string | number Name der Eigenschaft. Ein gültiger Bezeichner kann ohne Anführungszeichen stehen. Andere Namen (z. B. mit Bindestrich) brauchen Anführungszeichen. Zahlen werden in Strings umgewandelt.
$value any Beliebiger Ausdruck, der beim Erzeugen des Objekts ausgewertet und der Eigenschaft zugewiesen wird.
$[expression] string | symbol | any Berechneter Eigenschaftsname: Der Ausdruck in eckigen Klammern wird ausgewertet und in einen Eigenschaftsschlüssel umgewandelt (String oder Symbol).
$...source object | Iterable | null | undefined Spread-Syntax: kopiert die eigenen, aufzählbaren Eigenschaften von source flach in das neue Objekt. null und undefined werden ignoriert.
$__proto__ object | null Object.prototype Nicht berechneter Schlüssel __proto__: wert. Setzt den Prototyp des neuen Objekts, legt aber keine eigene Eigenschaft an.

Rückgabewert

Typ
object
Beschreibung
Ein neu erzeugtes, gewöhnliches Objekt mit den angegebenen Eigenschaften. Der Prototyp ist standardmäßig Object.prototype.

Beispiele

Einfaches Objekt anlegen und lesen

const user = {
  name: 'Anna',
  age: 32,
  'e-mail': 'anna@example.com', // Anführungszeichen wegen Bindestrich
  1: 'eins'                     // wird zum String '1'
};

console.log(user.name);
console.log(user['e-mail']);
console.log(Object.keys(user));
Anna anna@example.com [ '1', 'name', 'age', 'e-mail' ]

Kurzschreibweisen: Eigenschaft, Methode, berechneter Schlüssel

const createProduct = (id, title, price) => {
  const field = 'priceWithTax';
  return {
    id,             // entspricht id: id
    title,
    price,
    [field]: +(price * 1.19).toFixed(2),
    describe() {
      return `${this.title} kostet ${this.price} €`;
    }
  };
};

const p = createProduct(7, 'Tastatur', 50);
console.log(p.priceWithTax);
console.log(p.describe());
59.5 Tastatur kostet 50 €

Unveränderliches Update mit Spread (State-Management)

const defaults = { theme: 'light', lang: 'de', notifications: true };
const userSettings = { theme: 'dark' };

// Spätere Eigenschaften überschreiben frühere
const settings = { ...defaults, ...userSettings, updatedAt: '2024-05-01' };

console.log(settings);
console.log(defaults.theme); // Original bleibt unverändert
{ theme: 'dark', lang: 'de', notifications: true, updatedAt: '2024-05-01' } light

Getter, Setter und Prototyp per __proto__

const base = { greet() { return `Hallo, ${this.fullName}`; } };

const person = {
  __proto__: base,
  first: 'Max',
  last: 'Muster',
  get fullName() { return `${this.first} ${this.last}`; },
  set fullName(v) { [this.first, this.last] = v.split(' '); }
};

person.fullName = 'Erika Mustermann';
console.log(person.greet());
console.log(Object.getPrototypeOf(person) === base);
Hallo, Erika Mustermann true

// Wichtig · Fallstricke

  • Block oder Objekt? Am Anfang einer Anweisung wird { als Block gelesen. Eine Pfeilfunktion, die ein Objekt zurückgeben soll, braucht deshalb runde Klammern: () => ({ a: 1 }). Ohne Klammern liefert sie undefined.
  • Flache Kopie: { ...obj } kopiert verschachtelte Objekte nur als Referenz. Für tiefe Kopien gibt es structuredClone().
  • Spread ruft Setter nicht auf: Spread legt neue Eigenschaften an. Object.assign() dagegen weist zu und löst dabei Setter des Ziels aus. Getter der Quelle werden in beiden Fällen ausgewertet.
  • Reihenfolge der Schlüssel: Ganzzahl-ähnliche Schlüssel kommen zuerst, aufsteigend sortiert. Danach folgen String-Schlüssel in Einfügereihenfolge, dann Symbole.
  • Doppelte Schlüssel sind seit ES2015 auch im Strict Mode erlaubt; der letzte Wert gewinnt. Ausnahme: __proto__ darf als nicht berechneter Schlüssel nur einmal vorkommen, sonst gibt es einen SyntaxError.
  • this in Pfeilfunktionen als Eigenschaftswert zeigt nicht auf das Objekt. Nutze stattdessen die Methoden-Kurzform.
  • Kein JSON: Objektliterale erlauben Funktionen, undefined, Schlüssel ohne Anführungszeichen und abschließende Kommata. JSON erlaubt nichts davon.
  • Sicherheit: Übernimm Schlüssel aus Benutzereingaben (z. B. __proto__) nicht ungeprüft in Objekte, sonst droht Prototype Pollution. Für Wörterbücher eignen sich Object.create(null) oder Map.
  • Kompatibilität: Kurzschreibweisen und berechnete Schlüssel gibt es seit ES2015, Spread-Eigenschaften seit ES2018. Alle aktuellen Browser und Node.js unterstützen sie; der Internet Explorer nicht.