JSON
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Das JSON
Namensraumobjekt enthält statische Methoden zum Parsen von Werten aus und Konvertieren von Werten in JavaScript Object Notation (JSON).
Beschreibung
Im Gegensatz zu den meisten globalen Objekten ist JSON
kein Konstruktor. Sie können es weder mit dem new
-Operator verwenden noch das JSON
-Objekt als Funktion aufrufen. Alle Eigenschaften und Methoden von JSON
sind statisch (genau wie das Math
Objekt).
Unterschiede zwischen JavaScript und JSON
JSON ist eine Syntax zum Serialisieren von Objekten, Arrays, Zahlen, Zeichenfolgen, Booleans und null
. Es basiert auf der JavaScript-Syntax, ist aber von JavaScript unterschieden: Ein Großteil von JavaScript ist nicht JSON. Zum Beispiel:
- Objekte und Arrays
-
Eigenschaftsnamen müssen doppelt-angeführte Zeichenfolgen sein; Abschließende Kommata sind verboten.
- Zahlen
-
Führende Nullen sind untersagt. Ein Dezimalpunkt muss von mindestens einer Ziffer gefolgt werden.
NaN
undInfinity
werden nicht unterstützt.
Jeder JSON-Text ist ein gültiger JavaScript-Ausdruck, jedoch nur nach der JSON-Ergänzung Überarbeitung. Vor der Überarbeitung sind U+2028 ZEILENTRENNER und U+2029 ABSATZTRENNER in Zeichenkettenliteralen und Eigenschaftsschlüsseln in JSON erlaubt; dieselbe Verwendung in JavaScript-Zeichenkettenliteralen führt jedoch zu einem SyntaxError
.
Weitere Unterschiede umfassen, dass nur doppelt-angeführte Zeichenfolgen erlaubt sind und kein Support für undefined
oder Kommentare besteht. Für diejenigen, die ein nutzerfreundlicheres Konfigurationsformat basierend auf JSON verwenden möchten, gibt es JSON5, das vom Babel-Compiler verwendet wird, und das weiter verbreitete YAML.
Der gleiche Text kann auch unterschiedliche Werte in JavaScript-Objektliteralen im Vergleich zu JSON repräsentieren. Weitere Informationen finden Sie unter Objektliteral-Syntax vs. JSON.
Volle JSON-Grammatik
Die gültige JSON-Syntax ist formell durch die folgende Grammatik definiert, ausgedrückt in ABNF und kopiert aus dem IETF JSON Standard (RFC):
JSON-text = object / array begin-array = ws %x5B ws ; [ left square bracket begin-object = ws %x7B ws ; { left curly bracket end-array = ws %x5D ws ; ] right square bracket end-object = ws %x7D ws ; } right curly bracket name-separator = ws %x3A ws ; : colon value-separator = ws %x2C ws ; , comma ws = *( %x20 / ; Space %x09 / ; Horizontal tab %x0A / ; Line feed or New line %x0D ; Carriage return ) value = false / null / true / object / array / number / string false = %x66.61.6c.73.65 ; false null = %x6e.75.6c.6c ; null true = %x74.72.75.65 ; true object = begin-object [ member *( value-separator member ) ] end-object member = string name-separator value array = begin-array [ value *( value-separator value ) ] end-array number = [ minus ] int [ frac ] [ exp ] decimal-point = %x2E ; . digit1-9 = %x31-39 ; 1-9 e = %x65 / %x45 ; e E exp = e [ minus / plus ] 1*DIGIT frac = decimal-point 1*DIGIT int = zero / ( digit1-9 *DIGIT ) minus = %x2D ; - plus = %x2B ; + zero = %x30 ; 0 string = quotation-mark *char quotation-mark char = unescaped / escape ( %x22 / ; " quotation mark U+0022 %x5C / ; \ reverse solidus U+005C %x2F / ; / solidus U+002F %x62 / ; b backspace U+0008 %x66 / ; f form feed U+000C %x6E / ; n line feed U+000A %x72 / ; r carriage return U+000D %x74 / ; t tab U+0009 %x75 4HEXDIG ) ; uXXXX U+XXXX escape = %x5C ; \ quotation-mark = %x22 ; " unescaped = %x20-21 / %x23-5B / %x5D-10FFFF HEXDIG = DIGIT / %x41-46 / %x61-66 ; 0-9, A-F, or a-f ; HEXDIG equivalent to HEXDIG rule in [RFC5234] DIGIT = %x30-39 ; 0-9 ; DIGIT equivalent to DIGIT rule in [RFC5234]
Unbedeutende Leerzeichen können überall vorhanden sein, außer innerhalb eines JSONNumber
(Zahlen dürfen keine Leerzeichen enthalten) oder eines JSONString
(wo es als entsprechendes Zeichen in der Zeichenkette interpretiert wird oder einen Fehler verursachen würde). Die Tabulatoren (U+0009), Wagenrücklauf (U+000D), Zeilenumbruch (U+000A) und Leerzeichen (U+0020) sind die einzigen gültigen Leerzeichen-Zeichen.
Statische Eigenschaften
JSON[Symbol.toStringTag]
-
Der Anfangswert der
[Symbol.toStringTag]
Eigenschaft ist die Zeichenfolge"JSON"
. Diese Eigenschaft wird inObject.prototype.toString()
verwendet.
Statische Methoden
JSON.isRawJSON()
-
Prüft, ob ein Wert ein von
JSON.rawJSON()
zurückgegebenes Objekt ist. JSON.parse()
-
Parst ein Stück Zeichenfolgen-Text als JSON, transformiert optional den erzeugten Wert und dessen Eigenschaften und gibt den Wert zurück.
JSON.rawJSON()
-
Erstellt ein "rohes JSON"-Objekt, das ein Stück JSON-Text enthält. Wenn es zu JSON serialisiert wird, wird das rohe JSON-Objekt behandelt, als ob es bereits ein Stück JSON ist. Dieser Text muss gültiges JSON sein.
JSON.stringify()
-
Gibt eine JSON-Zeichenfolge zurück, die dem angegebenen Wert entspricht, und enthält optional nur bestimmte Eigenschaften oder ersetzt Eigenschaftswerte auf benutzerdefinierte Weise.
Beispiele
Beispiel JSON
{
"browsers": {
"firefox": {
"name": "Firefox",
"pref_url": "about:config",
"releases": {
"1": {
"release_date": "2004-11-09",
"status": "retired",
"engine": "Gecko",
"engine_version": "1.7"
}
}
}
}
}
Sie können die JSON.parse()
Methode verwenden, um die obige JSON-Zeichenfolge in ein JavaScript-Objekt umzuwandeln:
const jsonText = `{
"browsers": {
"firefox": {
"name": "Firefox",
"pref_url": "about:config",
"releases": {
"1": {
"release_date": "2004-11-09",
"status": "retired",
"engine": "Gecko",
"engine_version": "1.7"
}
}
}
}
}`;
console.log(JSON.parse(jsonText));
Verlustfreie Zahlendarstellung
JSON kann Zahlenliterale beliebiger Genauigkeit enthalten. Allerdings ist es nicht möglich, alle JSON-Zahlen genau in JavaScript darzustellen, da JavaScript eine Gleitkommadarstellung verwendet, die eine feste Genauigkeit hat. Zum Beispiel ist 12345678901234567890 === 12345678901234567000
in JavaScript wahr, da sie die gleiche Gleitkommadarstellung haben. Dies bedeutet, dass es keine JavaScript-Zahl gibt, die der 12345678901234567890
JSON-Zahl genau entspricht.
Angenommen, Sie haben eine genaue Darstellung einer Zahl (entweder über BigInt
oder eine benutzerdefinierte Bibliothek):
const data = {
// Using a BigInt here to store the exact value,
// but it can also be a custom high-precision number library,
// if the number might not be an integer.
gross_gdp: 12345678901234567890n,
};
Sie möchten sie serialisieren und dann zur gleichen genauen Zahl parsen. Es gibt mehrere Schwierigkeiten:
- Auf der Serialisierungsseite müssen Sie, um eine Zahl in JSON zu erhalten, eine Zahl an
JSON.stringify
übergeben, entweder über diereplacer
-Funktion oder über dietoJSON
-Methode. In beiden Fällen haben Sie jedoch bereits Präzision während der Zahlkonvertierung verloren. Wenn Sie eine Zeichenkette anJSON.stringify
übergeben, wird sie als Zeichenkette, nicht als Zahl serialisiert. - Auf der Parseseite können nicht alle Zahlen genau dargestellt werden. Beispielsweise gibt
JSON.parse("12345678901234567890")
12345678901234568000
zurück, da die Zahl auf die nächste darstellbare Zahl gerundet wird. Selbst wenn Sie einereviver
-Funktion verwenden, wird die Zahl bereits gerundet, bevor diereviver
-Funktion aufgerufen wird.
Es gibt im Allgemeinen zwei Möglichkeiten, sicherzustellen, dass Zahlen verlustfrei in JSON konvertiert und zurückgeparst werden: Eine beinhaltet eine JSON-Zahl, die andere eine JSON-Zeichenfolge. JSON ist ein Kommunikationsformat, daher ist es wahrscheinlich, wenn Sie JSON verwenden, dass Sie mit einem anderen System kommunizieren (HTTP-Anfrage, Speichern in Datenbank usw.). Die beste Wahl hängt vom Empfängersystem ab.
Verwendung von JSON-Zeichenfolgen
Wenn das Empfängersystem nicht dieselben JSON-Handhabungsfähigkeiten wie JavaScript besitzt und keine hochpräzisen Zahlen unterstützt, möchten Sie die Zahl möglicherweise als Zeichenkette serialisieren und sie dann auf der Empfängerseite als Zeichenkette behandeln. Dies ist auch die einzige Option im älteren JavaScript.
Um anzugeben, wie benutzerdefinierte Datentypen (einschließlich BigInt
) in JSON serialisiert werden sollen, fügen Sie entweder eine toJSON
-Methode zu Ihrem Datentyp hinzu oder verwenden Sie die replacer
-Funktion von JSON.stringify()
.
// Using toJSON() method
BigInt.prototype.toJSON = function () {
return this.toString();
};
const str1 = JSON.stringify(data);
// Using JSON.stringify() with replacer
const str2 = JSON.stringify(data, (key, value) => {
if (key === "gross_gdp") {
return value.toString();
}
return value;
});
In beiden Fällen sieht der JSON-Text aus wie {"gross_gdp":"12345678901234567890"}
, wobei der Wert eine Zeichenkette, keine Zahl ist. Dann können Sie auf der Empfängerseite das JSON parsen und die Zeichenkette verarbeiten.
Verwendung von JSON-Zahlen
Wenn der Empfänger dieser Nachricht native Unterstützung für hochpräzise Zahlen bietet (wie Python-Integers), ist es offensichtlich besser, Zahlen als JSON-Zahlen zu übergeben, da sie direkt in den hochpräzisen Typ geparst werden können, anstatt eine Zeichenkette aus JSON zu parsen und dann eine Zahl aus der Zeichenkette zu parsen. In JavaScript können Sie beliebige Datentypen zu JSON-Zahlen serialisieren, ohne zuerst einen Zahlenwert zu erzeugen (was zu einem Präzisionsverlust führt), indem Sie JSON.rawJSON()
verwenden, um genau festzulegen, wie der JSON-Quelltext aussehen soll.
// Using toJSON() method
BigInt.prototype.toJSON = function () {
return JSON.rawJSON(this.toString());
};
const str1 = JSON.stringify(data);
// Using JSON.stringify() with replacer
const str2 = JSON.stringify(data, (key, value) => {
if (key === "gross_gdp") {
return JSON.rawJSON(value.toString());
}
return value;
});
Der Text, der an JSON.rawJSON
übergeben wird, wird behandelt, als ob er bereits ein Stück JSON ist, sodass er nicht erneut als Zeichenkette serialisiert wird. Daher sieht der JSON-Text aus wie {"gross_gdp":12345678901234567890}
, wobei der Wert eine Zahl ist. Dieses JSON kann dann vom Empfänger geparst werden, ohne dass eine zusätzliche Verarbeitung erforderlich ist, vorausgesetzt, das Empfängersystem hat nicht dieselben Präzisionsbeschränkungen wie JavaScript.
Beim Parsen von JSON mit hochpräzisen Zahlen in JavaScript ist besondere Vorsicht geboten, da beim Aufrufen der reviver
-Funktion durch JSON.parse()
der Wert, den Sie erhalten, bereits geparst ist (und Präzision verloren hat). Sie können das context.source
Parameter der JSON.parse()
reviver
-Funktion verwenden, um die Zahl selbst neu zu parsen.
const parsedData = JSON.parse(str, (key, value, context) => {
if (key === "gross_gdp") {
// Or use the constructor of your custom high-precision number library
return BigInt(context.source);
}
return value;
});
// { gross_gdp: 12345678901234567890n }
Spezifikationen
Specification |
---|
ECMAScript Language Specification # sec-json-object |
Browser-Kompatibilität
BCD tables only load in the browser