Suche…


Einführung

JSON (JavaScript Object Notation) ist ein kompaktes Format für den Datenaustausch. Es ist für Menschen einfach zu lesen und zu schreiben, und Maschinen können leicht analysiert und generiert werden. Es ist wichtig zu wissen, dass JSON in JavaScript eine Zeichenfolge und kein Objekt ist.

Eine grundlegende Übersicht finden Sie auf der Website json.org, die auch Links zu Implementierungen des Standards in vielen verschiedenen Programmiersprachen enthält.

Syntax

  • JSON.parse (input [, reviver])
  • JSON.stringify (Wert [, Platzhalter [, Leerzeichen]])

Parameter

Parameter Einzelheiten
JSON.parse Parsen Sie eine JSON-Zeichenfolge
input(string) JSON-Zeichenfolge, die analysiert werden soll.
reviver(function) Gibt eine Umwandlung für die Eingabe-JSON-Zeichenfolge vor.
JSON.stringify Serialisieren Sie einen serialisierbaren Wert
value(string) Wert, der gemäß der JSON-Spezifikation serialisiert werden soll.
replacer(function oder String[] oder Number[]) Schließt selektiv bestimmte Eigenschaften des value .
space(String oder Number ) Wenn eine number wird, werden space für Leerzeichen der Lesbarkeit hinzugefügt. Wenn eine string bereitgestellt wird, wird die Zeichenfolge (die ersten 10 Zeichen) als Leerzeichen verwendet.

Bemerkungen

Die JSON- Dienstmethoden wurden zuerst in ECMAScript 5.1 §15.12 standardisiert .

Das Format wurde formal definiert in Der Antrag / Json-Medientyp für JSON (RFC 4627 Juli 2006), der später im JSON-Datenaustauschformat (RFC 7158 März 2013, ECMA-404 Oktober 2013 und RFC 7159 März 2014) aktualisiert wurde.

Verwenden Sie json2.js von Douglas Crockford, um diese Methoden in alten Browsern wie Internet Explorer 8 verfügbar zu machen.

Analysieren einer einfachen JSON-Zeichenfolge

Die JSON.parse() Methode analysiert einen String als JSON und gibt ein JavaScript- JSON.parse() , ein Array oder ein Objekt zurück:

const array = JSON.parse('[1, 2, "c", "d", {"e": false}]');
console.log(array); // logs: [1, 2, "c", "d", {e: false}]

Einen Wert serialisieren

Ein JavaScript-Wert kann mit der Funktion JSON.stringify in eine JSON-Zeichenfolge JSON.stringify werden.

JSON.stringify(value[, replacer[, space]])
  1. value Der Wert, der in eine JSON-Zeichenfolge konvertiert werden soll.
/* Boolean */  JSON.stringify(true)             // 'true'
/* Number  */  JSON.stringify(12)               // '12'
/* String  */  JSON.stringify('foo')            // '"foo"'
/* Object  */  JSON.stringify({})               // '{}'
               JSON.stringify({foo: 'baz'})     // '{"foo": "baz"}'
/* Array   */  JSON.stringify([1, true, 'foo']) // '[1, true, "foo"]'
/* Date    */  JSON.stringify(new Date())       // '"2016-08-06T17:25:23.588Z"'
/* Symbol  */  JSON.stringify({x:Symbol()})     // '{}'
  1. replacer Eine Funktion, die das Verhalten des Stringifizierungsprozesses oder eines Arrays von String- und Number-Objekten ändert, die als Whitelist zum Filtern der Eigenschaften des Wertobjekts dienen, das in den JSON-String aufgenommen werden soll. Wenn dieser Wert null ist oder nicht angegeben wird, werden alle Eigenschaften des Objekts in die resultierende JSON-Zeichenfolge aufgenommen.
// replacer as a function
function replacer (key, value) {
    // Filtering out properties
    if (typeof value === "string") {
        return
    }    
    return value
}

var foo = { foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7 }
JSON.stringify(foo, replacer)
// -> '{"week": 45, "month": 7}'
// replacer as an array
JSON.stringify(foo, ['foundation', 'week', 'month'])
// -> '{"foundation": "Mozilla", "week": 45, "month": 7}'
// only the `foundation`, `week`, and `month` properties are kept
  1. space Aus Gründen der Lesbarkeit kann die Anzahl der Leerzeichen für den Einzug als dritter Parameter angegeben werden.
JSON.stringify({x: 1, y: 1}, null, 2)  // 2 space characters will be used for indentation
/* output:
    {
      'x': 1,
      'y': 1
    }
*/

Alternativ kann ein Zeichenfolgewert angegeben werden, der zum Einrücken verwendet wird. Wenn Sie beispielsweise '\t' wird das Tabulatorzeichen für die Einrückung verwendet.

JSON.stringify({x: 1, y: 1}, null, '\t')
/* output:
    {
        'x': 1,
        'y': 1
    }
*/

Serialisierung mit einer Ersetzungsfunktion

Eine replacer kann zum Filtern oder Umwandeln von Werten verwendet werden, die serialisiert werden.

const userRecords = [
  {name: "Joe", points: 14.9, level: 31.5},
  {name: "Jane", points: 35.5, level: 74.4},
  {name: "Jacob", points: 18.5, level: 41.2},
  {name: "Jessie", points: 15.1, level: 28.1},
];

// Remove names and round numbers to integers to anonymize records before sharing
const anonymousReport = JSON.stringify(userRecords, (key, value) =>
  key === 'name'
    ? undefined
    : (typeof value === 'number' ? Math.floor(value) : value)
);

Dies erzeugt die folgende Zeichenfolge:

'[{"points":14,"level":31},{"points":35,"level":74},{"points":18,"level":41},{"points":15,"level":28}]'

Parsen mit einer Reviver-Funktion

Eine Reviver-Funktion kann verwendet werden, um den analysierten Wert zu filtern oder umzuwandeln.

5.1
var jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';

var data = JSON.parse(jsonString, function reviver(key, value) {
  return key === 'name' ? value.toUpperCase() : value;
});
6
const jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';

const data = JSON.parse(jsonString, (key, value) =>
  key === 'name' ? value.toUpperCase() : value
);

Dies führt zu folgendem Ergebnis:

[
  {
    'name': 'JOHN',
    'score': 51
  },
  {
    'name': 'JACK',
    'score': 17
  }
]

Dies ist besonders nützlich, wenn Daten gesendet werden müssen, die bei der Übertragung mit JSON serialisiert / codiert werden müssen, der Server jedoch deserialisiert / decodiert werden soll. Im folgenden Beispiel wurde ein Datum in seine ISO 8601-Darstellung codiert. Wir verwenden die Reviver-Funktion, um dies in einem JavaScript- Date zu analysieren.

5.1
var jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';

var data = JSON.parse(jsonString, function (key, value) {
  return (key === 'date') ? new Date(value) : value;
});
6
const jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';

const data = JSON.parse(jsonString, (key, value) =>
  key === 'date' ? new Date(value) : value
);

Es ist wichtig sicherzustellen, dass die Reviver-Funktion am Ende jeder Iteration einen nützlichen Wert zurückgibt. Wenn die Funktion reviver undefined zurückgibt, kein Wert oder die Ausführung gegen Ende der Funktion abfällt, wird die Eigenschaft aus dem Objekt gelöscht. Andernfalls wird die Eigenschaft als Rückgabewert neu definiert.

Klasseninstanzen serialisieren und wiederherstellen

Sie können eine benutzerdefinierte toJSON Methode und eine toJSON Funktion verwenden, um Instanzen Ihrer eigenen Klasse in JSON zu übertragen. Wenn ein Objekt eine toJSON Methode hat, wird das Ergebnis anstelle des Objekts selbst serialisiert.

6
function Car(color, speed) {
  this.color = color;
  this.speed = speed;
}

Car.prototype.toJSON = function() {
  return {
    $type: 'com.example.Car',
    color: this.color,
    speed: this.speed
  };
};

Car.fromJSON = function(data) {
  return new Car(data.color, data.speed);
};
6
class Car {
  constructor(color, speed) {
    this.color = color;
    this.speed = speed;
    this.id_ = Math.random();
  }

  toJSON() {
    return {
      $type: 'com.example.Car',
      color: this.color,
      speed: this.speed
    };
  }

  static fromJSON(data) {
    return new Car(data.color, data.speed);
  }
}
var userJson = JSON.stringify({
  name: "John",
  car: new Car('red', 'fast')
});

Dies erzeugt einen String mit folgendem Inhalt:

{"name":"John","car":{"$type":"com.example.Car","color":"red","speed":"fast"}}
var userObject = JSON.parse(userJson, function reviver(key, value) {
  return (value && value.$type === 'com.example.Car') ? Car.fromJSON(value) : value;
});

Dies erzeugt das folgende Objekt:

{
  name: "John",
  car: Car {
    color: "red",
    speed: "fast",
    id_: 0.19349242527065402
  }
}

JSON versus JavaScript-Literale

JSON steht für "JavaScript Object Notation", aber es ist kein JavaScript. Stellen Sie sich das nur als Datenserialisierungsformat vor , das direkt als JavaScript-Literal verwendet werden kann. Es ist jedoch nicht ratsam, JSON direkt auszuführen (dh durch eval() ), das von einer externen Quelle abgerufen wird. Funktionell unterscheidet sich JSON nicht sehr von XML oder YAML - einige Verwirrung kann vermieden werden, wenn JSON nur als Serialisierungsformat betrachtet wird, das JavaScript sehr ähnlich sieht.

Auch wenn der Name nur Objekte impliziert und obwohl die Mehrzahl der Anwendungsfälle durch eine Art API immer Objekte und Arrays sind, ist JSON nicht nur für Objekte oder Arrays. Die folgenden Grundtypen werden unterstützt:

  • String (zB "Hello World!" )
  • Nummer (zB 42 )
  • Boolean (zB true )
  • Der Wert null

undefined wird nicht in dem Sinne unterstützt, dass eine undefinierte Eigenschaft bei der Serialisierung in JSON nicht angegeben wird. Daher gibt es keine Möglichkeit, JSON zu deserialisieren und eine Eigenschaft zu erhalten, deren Wert nicht undefined .

Die Zeichenfolge "42" ist gültiger JSON. JSON muss nicht immer einen äußeren Umschlag aus "{...}" oder "[...]" .

Während nome JSON auch gültiges JavaScript und einige JavaScript auch gültige JSON sind, gibt es einige subtile Unterschiede zwischen beiden Sprachen, und keine der beiden Sprachen ist eine Untermenge der anderen.

Nehmen Sie die folgende JSON-Zeichenfolge als Beispiel:

{"color": "blue"}

Dies kann direkt in JavaScript eingefügt werden. Es ist syntaktisch gültig und liefert den korrekten Wert:

const skin = {"color": "blue"};

Wir wissen jedoch, dass "color" ein gültiger Bezeichnername ist und die Anführungszeichen um den Eigenschaftsnamen weggelassen werden können:

const skin = {color: "blue"};

Wir wissen auch, dass wir Anführungszeichen anstelle von Anführungszeichen verwenden können:

const skin = {'color': 'blue'};

Aber wenn wir beide Literale nehmen und als JSON behandeln würden, wird keine der beiden syntaktisch gültigen JSONs gelten:

{color: "blue"}
{'color': 'blue'}

JSON erfordert strengstens, dass alle Eigenschaftsnamen in doppelte Anführungszeichen gesetzt werden und Zeichenfolgenwerte ebenfalls in doppelte Anführungszeichen gesetzt werden.

Es ist üblich, dass JSON-Neulinge versuchen, Code-Auszüge mit JavaScript-Literalen als JSON zu verwenden und sich über die Syntaxfehler, die sie vom JSON-Parser erhalten, den Kopf zerkratzen.

Mehr Verwirrung tritt auf, wenn falsche Terminologie im Code oder in Konversation angewendet wird.

Ein allgemeines Anti-Pattern ist das Benennen von Variablen, die Nicht-JSON-Werte enthalten, als "json":

fetch(url).then(function (response) {
  const json = JSON.parse(response.data); // Confusion ensues!

  // We're done with the notion of "JSON" at this point,
  // but the concept stuck with the variable name.
});

Im obigen Beispiel ist response.data eine JSON-Zeichenfolge, die von einer API zurückgegeben wird. JSON stoppt bei der HTTP-Antwortdomäne. Die Variable mit dem "json" -Unenner enthält nur einen JavaScript-Wert (dies kann ein Objekt, ein Array oder sogar eine einfache Zahl sein!)

Ein weniger verwirrender Weg, um das oben zu schreiben, ist:

fetch(url).then(function (response) {
  const value = JSON.parse(response.data);

  // We're done with the notion of "JSON" at this point.
  // You don't talk about JSON after parsing JSON.
});

Entwickler neigen auch dazu, den Ausdruck "JSON-Objekt" häufig herumzuwerfen. Dies führt auch zu Verwirrung. Wie bereits erwähnt, muss eine JSON-Zeichenfolge kein Objekt als Wert enthalten. "JSON-String" ist ein besserer Begriff. Genauso wie "XML-String" oder "YAML-String". Sie erhalten eine Zeichenfolge, Sie analysieren sie und Sie erhalten einen Wert.

Zyklische Objektwerte

Nicht alle Objekte können in eine JSON-Zeichenfolge konvertiert werden. Wenn ein Objekt über zyklische Selbstreferenzen verfügt, schlägt die Konvertierung fehl.

Dies ist normalerweise der Fall für hierarchische Datenstrukturen, bei denen sich Eltern und Kind auf einander beziehen:

const world = {
  name: 'World',
  regions: []
};

world.regions.push({
  name: 'North America',
  parent: 'America'
});
console.log(JSON.stringify(world));
// {"name":"World","regions":[{"name":"North America","parent":"America"}]}

world.regions.push({
  name: 'Asia',
  parent: world
});

console.log(JSON.stringify(world));
// Uncaught TypeError: Converting circular structure to JSON

Sobald der Prozess einen Zyklus erkennt, wird die Ausnahme ausgelöst. Ohne Zykluserkennung wäre die Zeichenfolge unendlich lang.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow