JSON.stringify()
Baseline
Weitgehend verfügbar
Diese Funktion ist gut etabliert und funktioniert auf vielen Geräten und in vielen Browserversionen. Sie ist seit Juli 2015 browserübergreifend verfügbar.
Die statische Methode JSON.stringify() wandelt einen JavaScript-Wert in einen JSON-String um. Optional können Werte durch eine replacer-Funktion ersetzt oder über ein replacer-Array nur bestimmte Eigenschaften in die Ausgabe aufgenommen werden.
Probieren Sie es aus
console.log(JSON.stringify({ x: 5, y: 6 }));
// Expected output: '{"x":5,"y":6}'
console.log(
JSON.stringify([new Number(3), new String("false"), new Boolean(false)]),
);
// Expected output: '[3,"false",false]'
console.log(JSON.stringify({ x: [10, undefined, function () {}, Symbol("")] }));
// Expected output: '{"x":[10,null,null,null]}'
console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
// Expected output: '"2006-01-02T15:04:05.000Z"'
Syntax
JSON.stringify(value)
JSON.stringify(value, replacer)
JSON.stringify(value, replacer, space)
Parameter
value-
Der Wert, der in einen JSON-String umgewandelt werden soll.
replacerOptional-
Eine Funktion, die das Verhalten bei der Umwandlung in einen String verändert, oder ein Array aus Strings und Zahlen, das festlegt, welche Eigenschaften von
valuein die Ausgabe aufgenommen werden. Istreplacerein Array, werden alle Elemente dieses Arrays, die weder Strings noch Zahlen sind (als primitive Werte oder Wrapper-Objekte), einschließlichSymbol-Werten, vollständig ignoriert. Istreplacerweder eine Funktion noch ein Array (z. B.nulloder nicht angegeben), werden alle Eigenschaften des Objekts mit String-Schlüsseln in den resultierenden JSON-String aufgenommen. spaceOptional-
Ein String oder eine Zahl, mit der zur besseren Lesbarkeit Leerraum (einschließlich Einrückungen, Zeilenumbrüchen usw.) in den ausgegebenen JSON-String eingefügt wird.
Ist dies eine Zahl, gibt sie die Anzahl der für die Einrückung verwendeten Leerzeichen an, begrenzt auf 10 (das heißt, jede Zahl größer als
10wird wie10behandelt). Werte kleiner als 1 bedeuten, dass keine Leerzeichen verwendet werden.Ist dies ein String, wird der String (oder, falls er länger ist, seine ersten 10 Zeichen) vor jedem verschachtelten Objekt oder Array eingefügt.
Ist
spaceweder ein String noch eine Zahl (jeweils als primitiver Wert oder Wrapper-Objekt möglich) – beispielsweisenulloder nicht angegeben –, wird kein Leerraum verwendet.
Rückgabewert
Ein JSON-String, der den angegebenen Wert darstellt, oder undefined.
Ausnahmen
Beschreibung
JSON.stringify() wandelt einen Wert in die JSON-Notation um, die diesen Wert darstellt. Werte werden folgendermaßen in Strings umgewandelt:
Boolean-,Number-,String- undBigInt-Objekte (erzeugbar mitObject()) werden bei der Umwandlung entsprechend den üblichen Konvertierungsregeln in ihre jeweiligen primitiven Werte umgewandelt.Symbol-Objekte (erzeugbar mitObject()) werden wie gewöhnliche Objekte behandelt.- Der Versuch,
BigInt-Werte zu serialisieren, löst eine Ausnahme aus. Verfügt der BigInt-Wert jedoch über einetoJSON()-Methode (durch Monkey-Patching:BigInt.prototype.toJSON = ...), kann diese Methode das Ergebnis der Serialisierung liefern. Diese Einschränkung stellt sicher, dass ein geeignetes Verhalten für die Serialisierung (und sehr wahrscheinlich auch für die zugehörige Deserialisierung) stets ausdrücklich vom Benutzer bereitgestellt wird. undefined-,Function- undSymbol-Werte sind keine gültigen JSON-Werte. Werden solche Werte bei der Umwandlung angetroffen, werden sie entweder ausgelassen (wenn sie in einem Objekt vorkommen) oder durchnullersetzt (wenn sie in einem Array vorkommen).JSON.stringify()kannundefinedzurückgeben, wenn „reine“ Werte wie beiJSON.stringify(() => {})oderJSON.stringify(undefined)übergeben werden.- Die Zahlen
InfinityundNaNsowie der Wertnullwerden alle alsnullbehandelt. (Anders als die Werte im vorherigen Punkt werden sie jedoch niemals ausgelassen.) - Arrays werden als Arrays serialisiert (in eckige Klammern eingeschlossen). Nur Array-Indizes von 0 bis einschließlich
length - 1werden serialisiert; andere Eigenschaften werden ignoriert. - Das spezielle, mit
JSON.rawJSON()erzeugte Raw-JSON-Objekt wird als der darin enthaltene unveränderte JSON-Text serialisiert (durch Zugriff auf seine EigenschaftrawJSON). - Für andere Objekte gilt:
-
Alle Eigenschaften mit
Symbol-Schlüsseln werden vollständig ignoriert, auch wenn der Parameterreplacerverwendet wird. -
Verfügt der Wert über eine
toJSON()-Methode, bestimmt diese, welche Daten serialisiert werden. Statt des Objekts wird der Wert serialisiert, den die aufgerufenetoJSON()-Methode zurückgibt.JSON.stringify()rufttoJSONmit einem Parameter auf, demkey. Dieser hat dieselbe Bedeutung wie der Parameterkeyder Funktionreplacer:- wenn dieses Objekt der Wert einer Eigenschaft ist: der Name der Eigenschaft
- wenn es sich in einem Array befindet: der Index im Array als String
- wenn
JSON.stringify()direkt mit diesem Objekt aufgerufen wurde: ein leerer String
Alle
Temporal-Objekte implementieren die MethodetoJSON(), die einen String zurückgibt (denselben wie ein Aufruf vontoString()). Daher werden sie als Strings serialisiert. Ebenso implementierenDate-ObjektetoJSON(), das denselben Wert wietoISOString()zurückgibt. -
Es werden nur eigene aufzählbare Eigenschaften berücksichtigt. Das bedeutet, dass
Map,Setusw. zu"{}"werden. Mit dem Parameterreplacerkönnen Sie sie in eine nützlichere Darstellung serialisieren.Die Eigenschaften werden mit demselben Algorithmus wie bei
Object.keys()durchlaufen. Seine Reihenfolge ist eindeutig festgelegt und über Implementierungen hinweg stabil. Beispielsweise erzeugtJSON.stringifyfür dasselbe Objekt stets denselben String, undJSON.parse(JSON.stringify(obj))erzeugt ein Objekt mit derselben Schlüsselreihenfolge wie das Original (vorausgesetzt, das Objekt lässt sich vollständig als JSON serialisieren).
-
Der Parameter replacer
Der Parameter replacer kann eine Funktion oder ein Array sein.
Bei einem Array geben seine Elemente die Namen der Objekteigenschaften an, die in den resultierenden JSON-String aufgenommen werden sollen. Nur String- und Zahlenwerte werden berücksichtigt; Symbol-Schlüssel werden ignoriert.
Als Funktion erhält replacer zwei Parameter: den key und den value, der in einen String umgewandelt wird. Das Objekt, in dem der Schlüssel gefunden wurde, wird als this-Kontext von replacer bereitgestellt.
Die Funktion replacer wird auch für das anfängliche Objekt aufgerufen, das in einen String umgewandelt wird. In diesem Fall ist key ein leerer String (""). Anschließend wird sie für jede Eigenschaft des umzuwandelnden Objekts oder Arrays aufgerufen. Array-Indizes werden als String in key übergeben. Der aktuelle Eigenschaftswert wird für die Umwandlung durch den Rückgabewert von replacer ersetzt. Das bedeutet:
- Wenn Sie eine Zahl, einen String, einen booleschen Wert oder
nullzurückgeben, wird dieser Wert direkt serialisiert und als Eigenschaftswert verwendet. (Die Rückgabe eines BigInt-Werts löst ebenfalls eine Ausnahme aus.) - Wenn Sie
Function,Symboloderundefinedzurückgeben, wird die Eigenschaft nicht in die Ausgabe aufgenommen. - Wenn Sie ein anderes Objekt zurückgeben, wird dieses rekursiv in einen String umgewandelt, wobei die Funktion
replacerfür jede Eigenschaft aufgerufen wird.
Hinweis:
Wenn Sie JSON parsen, das mit replacer-Funktionen erzeugt wurde, sollten Sie wahrscheinlich den Parameter reviver verwenden, um die umgekehrte Operation auszuführen.
Normalerweise verschieben sich die Indizes von Array-Elementen nicht (selbst wenn ein Element einen ungültigen Wert wie eine Funktion hat, wird es zu null, statt ausgelassen zu werden). Mit der Funktion replacer können Sie die Reihenfolge der Array-Elemente steuern, indem Sie ein anderes Array zurückgeben.
Der Parameter space
Mit dem Parameter space lässt sich der Leerraum im endgültigen String steuern.
- Ist er eine Zahl, wird jede weitere Verschachtelungsebene bei der Umwandlung um entsprechend viele Leerzeichen eingerückt.
- Ist er ein String, wird jede weitere Verschachtelungsebene mit diesem String eingerückt.
Eine Einrückungsebene ist niemals länger als 10 Zeichen. Zahlenwerte für space werden auf 10 begrenzt und String-Werte auf 10 Zeichen gekürzt.
Beispiele
>JSON.stringify verwenden
JSON.stringify({}); // '{}'
JSON.stringify(true); // 'true'
JSON.stringify("foo"); // '"foo"'
JSON.stringify([1, "false", false]); // '[1,"false",false]'
JSON.stringify([NaN, null, Infinity]); // '[null,null,null]'
JSON.stringify({ x: 5 }); // '{"x":5}'
JSON.stringify(new Date(1906, 0, 2, 15, 4, 5));
// '"1906-01-02T15:04:05.000Z"'
JSON.stringify({ x: 5, y: 6 });
// '{"x":5,"y":6}'
JSON.stringify([new Number(3), new String("false"), new Boolean(false)]);
// '[3,"false",false]'
// String-keyed array elements are not enumerable and make no sense in JSON
const a = ["foo", "bar"];
a["baz"] = "quux"; // a: [ 0: 'foo', 1: 'bar', baz: 'quux' ]
JSON.stringify(a);
// '["foo","bar"]'
JSON.stringify({ x: [10, undefined, function () {}, Symbol("")] });
// '{"x":[10,null,null,null]}'
// Standard data structures
JSON.stringify([
new Set([1]),
new Map([[1, 2]]),
new WeakSet([{ a: 1 }]),
new WeakMap([[{ a: 1 }, 2]]),
]);
// '[{},{},{},{}]'
// TypedArray
JSON.stringify([new Int8Array([1]), new Int16Array([1]), new Int32Array([1])]);
// '[{"0":1},{"0":1},{"0":1}]'
JSON.stringify([
new Uint8Array([1]),
new Uint8ClampedArray([1]),
new Uint16Array([1]),
new Uint32Array([1]),
]);
// '[{"0":1},{"0":1},{"0":1},{"0":1}]'
JSON.stringify([new Float32Array([1]), new Float64Array([1])]);
// '[{"0":1},{"0":1}]'
// toJSON()
JSON.stringify({
x: 5,
y: 6,
toJSON() {
return this.x + this.y;
},
});
// '11'
// Symbols:
JSON.stringify({ x: undefined, y: Object, z: Symbol("") });
// '{}'
JSON.stringify({ [Symbol("foo")]: "foo" });
// '{}'
JSON.stringify({ [Symbol.for("foo")]: "foo" }, [Symbol.for("foo")]);
// '{}'
JSON.stringify({ [Symbol.for("foo")]: "foo" }, (k, v) => {
if (typeof k === "symbol") {
return "a symbol";
}
});
// undefined
// Non-enumerable properties:
JSON.stringify(
Object.create(null, {
x: { value: "x", enumerable: false },
y: { value: "y", enumerable: true },
}),
);
// '{"y":"y"}'
// BigInt values throw
JSON.stringify({ x: 2n });
// TypeError: BigInt value can't be serialized in JSON
Eine Funktion als replacer verwenden
function replacer(key, value) {
// Filtering out properties
if (typeof value === "string") {
return undefined;
}
return value;
}
const foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
JSON.stringify(foo, replacer);
// '{"week":45,"month":7}'
Wenn replacer zwischen dem anfänglichen Objekt und einer Eigenschaft mit einem leeren String als Schlüssel unterscheiden soll (da in beiden Fällen ein leerer String als Schlüssel und möglicherweise ein Objekt als Wert übergeben wird), müssen Sie die Anzahl der Aufrufe mitzählen (nach dem ersten Aufruf handelt es sich um einen tatsächlichen leeren String-Schlüssel).
function makeReplacer() {
let isInitial = true;
return (key, value) => {
if (isInitial) {
isInitial = false;
return value;
}
if (key === "") {
// Omit all properties with name "" (except the initial object)
return undefined;
}
return value;
};
}
const replacer = makeReplacer();
console.log(JSON.stringify({ "": 1, b: 2 }, replacer)); // "{"b":2}"
Ein Array als replacer verwenden
const foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
JSON.stringify(foo, ["week", "month"]);
// '{"week":45,"month":7}', only keep "week" and "month" properties
Den Parameter space verwenden
Die Ausgabe mit einem Leerzeichen einrücken:
console.log(JSON.stringify({ a: 2 }, null, " "));
/*
{
"a": 2
}
*/
Die Verwendung eines Tabulatorzeichens ahmt das übliche Erscheinungsbild einer formatierten Ausgabe nach:
console.log(JSON.stringify({ uno: 1, dos: 2 }, null, "\t"));
/*
{
"uno": 1,
"dos": 2
}
*/
Verhalten von toJSON()
Wenn Sie toJSON() für ein Objekt definieren, können Sie dessen Serialisierungsverhalten überschreiben.
const obj = {
data: "data",
toJSON(key) {
return key ? `Now I am a nested object under key '${key}'` : this;
},
};
JSON.stringify(obj);
// '{"data":"data"}'
JSON.stringify({ obj });
// '{"obj":"Now I am a nested object under key 'obj'"}'
JSON.stringify([obj]);
// '["Now I am a nested object under key '0'"]'
Problem bei der Serialisierung zirkulärer Referenzen
Da das JSON-Format keine Objektreferenzen unterstützt (obwohl ein IETF-Entwurf existiert), wird ein TypeError ausgelöst, wenn versucht wird, ein Objekt mit zirkulären Referenzen zu kodieren.
const circularReference = {};
circularReference.myself = circularReference;
// Serializing circular references throws "TypeError: cyclic object value"
JSON.stringify(circularReference);
Um zirkuläre Referenzen zu serialisieren, können Sie eine Bibliothek verwenden, die diese unterstützt (z. B. cycle.js von Douglas Crockford), oder selbst eine Lösung implementieren. Dazu müssen Sie die zirkulären Referenzen finden und durch serialisierbare Werte ersetzen (oder sie entfernen).
Wenn Sie JSON.stringify() verwenden, um eine tiefe Kopie eines Objekts zu erstellen, können Sie stattdessen structuredClone() verwenden, das zirkuläre Referenzen unterstützt. Auch JavaScript-Engine-APIs für die binäre Serialisierung, beispielsweise v8.serialize(), unterstützen zirkuläre Referenzen.
JSON.stringify() mit localStorage verwenden
Wenn Sie ein von Ihren Benutzern erstelltes Objekt speichern und seine Wiederherstellung auch nach dem Schließen des Browsers ermöglichen möchten, zeigt das folgende Beispiel eine mögliche Anwendung von JSON.stringify():
// Creating an example of JSON
const session = {
screens: [],
state: true,
};
session.screens.push({ name: "screenA", width: 450, height: 250 });
session.screens.push({ name: "screenB", width: 650, height: 350 });
session.screens.push({ name: "screenC", width: 750, height: 120 });
session.screens.push({ name: "screenD", width: 250, height: 60 });
session.screens.push({ name: "screenE", width: 390, height: 120 });
session.screens.push({ name: "screenF", width: 1240, height: 650 });
// Converting the JSON string with JSON.stringify()
// then saving with localStorage in the name of session
localStorage.setItem("session", JSON.stringify(session));
// Example of how to transform the String generated through
// JSON.stringify() and saved in localStorage in JSON object again
const restoredSession = JSON.parse(localStorage.getItem("session"));
// Now restoredSession variable contains the object that was saved
// in localStorage
console.log(restoredSession);
Wohlgeformtes JSON.stringify()
Engines, die die Spezifikation für wohlgeformtes JSON.stringify implementieren, wandeln isolierte Surrogat-Codepunkte (jeden Codepunkt von U+D800 bis U+DFFF) mithilfe von Unicode-Escape-Sequenzen in Strings um, statt sie wörtlich auszugeben (und damit isolierte Surrogat-Codepunkte auszugeben). Vor dieser Änderung konnten solche Strings nicht als gültiges UTF-8 oder UTF-16 kodiert werden:
JSON.stringify("\uD800"); // '"�"'
Mit dieser Änderung stellt JSON.stringify() isolierte Surrogat-Codepunkte jedoch durch JSON-Escape-Sequenzen dar, die als gültiges UTF-8 oder UTF-16 kodiert werden können:
JSON.stringify("\uD800"); // '"\\ud800"'
Diese Änderung sollte abwärtskompatibel sein, solange Sie das Ergebnis von JSON.stringify() an APIs wie JSON.parse() übergeben, die jeden gültigen JSON-Text akzeptieren. Diese behandeln Unicode-Escape-Sequenzen für isolierte Surrogat-Codepunkte genauso wie die isolierten Surrogat-Codepunkte selbst. Nur wenn Sie das Ergebnis von JSON.stringify() direkt auswerten, müssen Sie die beiden möglichen Kodierungen dieser Codepunkte durch JSON.stringify() sorgfältig berücksichtigen.
Spezifikationen
| Spezifikation |
|---|
| ECMAScript® 2027 Language Specification> # sec-json.stringify> |