← Alle Artikel

JSON vs. JavaScript-Objekt: Warum einfache Anführungszeichen nicht erlaubt sind

Viele Entwickler behandeln JS-Objektliterale wie JSON. Sie sind nicht dasselbe: einfache Anführungszeichen, unquotierte Schlüssel, nachgestellte Kommas, undefined, NaN — hier jeder Unterschied mit Beispielen.

Du fügst etwas, das wie gültige Daten aussieht, in einen JSON-Parser ein und er wirft sofort SyntaxError: Unexpected token '''. Die Daten kommen aus deinem JavaScript-Quellcode und sehen völlig vernünftig aus —— aber JSON und JavaScript-Object-Literals sind nicht dasselbe Format, und die Unterschiede zählen mehr, als die meisten Entwickler bemerken.

Die kurze Antwort: JSON unterstützt keine einfachen Anführungszeichen

Einfache Anführungszeichen sind in JSON schlichtweg illegal. Jeder String —— Keys wie Werte —— muss doppelte Anführungszeichen nutzen. Keine Ausnahmen.

// ❌ Ungültiges JSON —— einfach gequotete Strings
{ 'name': 'Ada Lovelace', 'active': true }

// ✅ Gültiges JSON
{ "name": "Ada Lovelace", "active": true }

Der Fehler in unterschiedlichen Umgebungen:

// Chrome / Node.js (V8)
SyntaxError: Unexpected token "'", "{'name':..." is not valid JSON

// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data

// Safari
SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSON

Safaris Fehlermeldung ist die hilfreichste —— sie sagt dir genau, was das Problem ist. Die anderen melden nur das unerwartete Zeichen.

Warum verlangt JSON doppelte Anführungszeichen?

JSON wurde von Douglas Crockford 2001 definiert und als RFC 8259 standardisiert. Die Grammatik spezifiziert genau einen String-Delimiter: das doppelte Anführungszeichen (U+0022). Einfache Anführungszeichen sind in der Grammatik schlicht nicht vorhanden.

Der Grund ist Einfachheit. JSON ist ein Datenaustauschformat, gedacht für Parsing in jeder Sprache, nicht nur JavaScript. Indem die Spec einen einzigen Quoting-Stil vorschreibt, eliminiert sie eine ganze Klasse von Mehrdeutigkeit. Parser in Go, Python, Java, Rust und jeder anderen Sprache implementieren exakt dieselbe Regel.

JSON vs. JavaScript-Object-Literal: die vollständigen Unterschiede

Einfache Anführungszeichen sind nur einer von mehreren Unterschieden. Das vollständige Bild:

1. Keys müssen Strings in doppelten Anführungszeichen sein

// ❌ JavaScript-Object-Literal —— nackter Key, einfach gequoteter Key
{ name: "Ada", 'score': 98 }

// ✅ JSON —— alle Keys sind Strings in doppelten Anführungszeichen
{ "name": "Ada", "score": 98 }

JavaScript-Object-Literals akzeptieren nackte Identifier, einfach gequotete Strings und doppelt gequotete Strings als Keys. JSON akzeptiert nur doppelt gequotete Strings.

2. Keine Trailing Commas

// ❌ Ungültiges JSON
{ "name": "Ada", "score": 98, }
//                            ^ Trailing Comma

// ✅ Gültiges JSON
{ "name": "Ada", "score": 98 }

Modernes JavaScript erlaubt explizit Trailing Commas. JSON nicht —— siehe unseren vollständigen Guide zu Trailing Commas in JSON.

3. Keine Kommentare

// ❌ Ungültiges JSON
{
  // Benutzerprofil
  "name": "Ada"
}

// ✅ JSON hat keine Kommentar-Syntax
{ "name": "Ada" }

JSON hat überhaupt keine Kommentar-Syntax. Wenn du Kommentare in Config-Dateien brauchst, denk an das JSONC-Format (JSON-with-Comments), das von VS Code-Settings, TypeScripts tsconfig.json und mehreren Config-Datei-Parsern unterstützt wird.

4. Kein undefined, keine Funktionen oder Symbols

// JavaScript-Objekt —— akzeptiert nicht serialisierbare Werte
const obj = {
  fn: () => 42,         // Funktion
  sym: Symbol('id'),    // Symbol
  val: undefined,       // undefined
};

// JSON.stringify lässt sie still fallen oder wandelt sie um
JSON.stringify(obj);
// → '{}'   (alle drei Properties verschwinden oder werden null)

JSON unterstützt genau sechs Werttypen: string, number, boolean (true/false), null, object und array. Funktionen, Symbols und undefined haben keine JSON-Repräsentation. JSON.stringify() lässt Objekt-Properties mit diesen Werten still fallen und wandelt sie in Arrays in null um.

5. Kein NaN oder Infinity

JSON.stringify({ ratio: NaN, limit: Infinity });
// → '{"ratio":null,"limit":null}'
// NaN und Infinity werden null —— still!

JSON.parse('{"ratio": NaN}');
// → SyntaxError: Unexpected token 'N'

NaN und Infinity sind gültige JavaScript-Zahlenwerte, aber kein Teil der JSON-Zahlspezifikation. JSON.stringify() wandelt sie beim Ausgeben in null um; JSON.parse() lehnt sie beim Einlesen ab. Diese Asymmetrie ist eine häufige Quelle subtiler Bugs.

6. Zahlen: kein Hex, keine führenden Nullen, kein +

// ❌ Ungültiges JSON
{ "flags": 0xFF, "code": 007, "delta": +1.5 }

// ✅ Gültiges JSON
{ "flags": 255, "code": 7, "delta": 1.5 }

JSON-Zahlen müssen dezimal sein, dürfen nicht mit explizitem +-Vorzeichen beginnen und dürfen keine führenden Nullen haben (außer der einzelnen Ziffer 0 vor einem Dezimalpunkt). Hexadezimal- und Oktal-Literale sind kein gültiges JSON.

7. Keine mehrzeiligen Strings

// ❌ Ungültiges JSON —— literaler Zeilenumbruch im String
{ "bio": "Line one
Line two" }

// ✅ Nutze die Escape-Sequenz
{ "bio": "Line one\nLine two" }

8. Berechnete Keys, Symbol-Keys und Method-Shorthand

Drei weitere reine JS-Features, die wie JSON aussehen, aber keine Entsprechung haben:

// ❌ Berechnete Property-Namen —— evaluiert, nicht literal
const k = "id";
const obj = { [k]: 1, [`user_${k}`]: 1 };
// JSON hat keine Ausdrücke; der Key muss ein literaler doppelt gequoteter String sein.

// ❌ Symbol-Keys —— still von JSON.stringify weggeworfen
const tag = Symbol('tag');
JSON.stringify({ [tag]: 'admin' });  // → '{}'

// ❌ Method-Shorthand —— Funktionen werden weggeworfen/weggelassen
const obj = { greet() { return 'hi'; } };
JSON.stringify(obj);  // → '{}'

Wenn du eines davon brauchst, serialisiere eine JSON-förmige Projektion deines Objekts —— JSON.stringify() erzeugt nur String-Keys und die sechs JSON-Werttypen.

Eine schnelle Konvertierungs-Cheatsheet

JavaScript-Object-LiteralGültiges JSON-Äquivalent
{ name: "Ada" }{"name":"Ada"}
{ 'name': 'Ada' }{"name":"Ada"}
{ a: 1, }{"a":1}
{ val: undefined }{} (Property weggeworfen)
{ n: NaN }{"n":null}
{ n: Infinity }{"n":null}
{ fn: () => 1 }{} (Property weggeworfen)
0xFF255

Der sicherste Weg, ein JS-Objekt in JSON zu konvertieren

Versuche niemals, ein JavaScript-Objekt durch manuelles Anführungszeichen-Editieren in JSON zu konvertieren. Nutze JSON.stringify() —— es behandelt jeden Grenzfall korrekt:

const obj = { name: 'Ada', score: 98, active: true };

// Kompakt
JSON.stringify(obj);
// → '{"name":"Ada","score":98,"active":true}'

// Pretty-print mit 2-Space-Einrückung
JSON.stringify(obj, null, 2);
// → '{
  "name": "Ada",
  "score": 98,
  "active": true
}'

Das zweite Argument von JSON.stringify() ist ein replacer —— du kannst ein Array von Key-Namen übergeben, um nur diese Properties einzuschließen, oder eine Funktion, um Werte zu transformieren:

// Nur bestimmte Keys einschließen
JSON.stringify(obj, ['name', 'score'], 2);
// → '{
  "name": "Ada",
  "score": 98
}'

// Custom-replacer —— undefined in null umwandeln
JSON.stringify({ a: 1, b: undefined }, (key, value) =>
  value === undefined ? null : value
);
// → '{"a":1,"b":null}'

Wenn du ein JS-Object-Literal als String bekommst

Manchmal bekommst du Daten, die wie JSON aussehen, aber tatsächlich ein JavaScript-Object-Literal sind —— etwa aus einer Logdatei, einem Debug-Tool oder einer API, die sich nicht an die Spec gehalten hat. In dem Fall scheitert JSON.parse() und du hast zwei Optionen:

  • Einen Repair-Parser nutzen —— wandelt einfache Anführungszeichen in doppelte um, entfernt Trailing Commas, setzt nackte Keys in Anführungszeichen und behandelt alle anderen Unterschiede automatisch. Der sicherste Ansatz für nicht vertrauenswürdiges Input.
  • eval() oder Function() nutzen —— funktioniert technisch für gültiges JavaScript, ist aber ein ernsthaftes Sicherheitsrisiko, wenn die Quelle nicht voll vertrauenswürdig ist. Tu das niemals mit User-Eingaben.

Häufig gestellte Fragen

Unterstützt JSON einfache Anführungszeichen?

Nein. Die JSON-Grammatik (RFC 8259) definiert genau einen String-Delimiter —— das doppelte Anführungszeichen. Keys wie Werte müssen doppelte Anführungszeichen nutzen; einfache Anführungszeichen werfen einen SyntaxError.

Was ist der Unterschied zwischen JSON und einem JavaScript-Objekt?

JSON ist ein striktes Textformat; ein JavaScript-Object-Literal ist nachsichtiger Code. JS erlaubt einfache Anführungszeichen, ungequotete Keys, Trailing Commas, Kommentare, undefined, NaN, Funktionen und Hex-Zahlen —— nichts davon ist gültiges JSON. Siehe die vollständige Cheatsheet oben und das Primer bei Was ist JSON?

Wie konvertiere ich ein JavaScript-Objekt in JSON?

Nutze JSON.stringify() —— editiere niemals Anführungszeichen von Hand. Es behandelt jeden Grenzfall, lässt nicht-serialisierbare Werte fallen und escapt Strings korrekt.

Warum kann ich eval() nicht nutzen, um ein JS-Object-Literal zu parsen?

eval() führt beliebigen Code aus, also ein ernsthaftes Sicherheitsrisiko bei nicht vertrauenswürdigem Input. Nutze stattdessen einen Repair-Parser (oder JSON Fix), um ein JS-Object-Literal sicher in gültiges JSON zu konvertieren.

Einfache Anführungszeichen sofort beheben

Wenn du ein JavaScript-Object-Literal hast, das du gerade in gültiges JSON konvertieren musst, übernimmt JSON Fix die Konvertierung automatisch. Es wandelt einfache Anführungszeichen in doppelte um, setzt nackte Keys in Anführungszeichen, entfernt Trailing Commas und behebt alle anderen oben aufgeführten Unterschiede —— in deinem Browser, ohne dass Daten an einen Server gesendet werden.