Zoeken…
Invoering
JSON (JavaScript Object Notation) is een lichtgewicht data-uitwisselingsformaat. Het is gemakkelijk voor mensen om te lezen en te schrijven en voor machines om te analyseren en te genereren. Het is belangrijk om te beseffen dat JSON in JavaScript een string is en geen object.
Een basisoverzicht is te vinden op de json.org- website, die ook koppelingen naar implementaties van de standaard in veel verschillende programmeertalen bevat.
Syntaxis
- JSON.parse (input [, reviver])
- JSON.stringify (waarde [, vervanger [, spatie]])
parameters
Parameter | Details |
---|---|
JSON.parse | Parseer een JSON-string |
input(string) | JSON-reeks die moet worden geparseerd. |
reviver(function) | Schrijft een transformatie voor de ingevoerde JSON-string. |
JSON.stringify | Serialiseer een serialiseerbare waarde |
value(string) | Waarde die moet worden geserialiseerd volgens de JSON-specificatie. |
replacer(function of String[] of Number[]) | Selectief bevat bepaalde eigenschappen van de value object. |
space(String of Number ) | Wanneer een number is, dan space zal aantal spaties ingevoegd leesbaarheid. Als een string wordt opgegeven, wordt de tekenreeks (eerste 10 tekens) gebruikt als witruimte. |
Opmerkingen
De JSON-hulpprogramma's werden eerst gestandaardiseerd in ECMAScript 5.1 §15.12 .
Het formaat werd formeel gedefinieerd in De applicatie / json Media Type voor JSON (RFC 4627 juli 2006), dat later werd bijgewerkt in het JSON Data Interchange Format (RFC 7158 maart 2013, ECMA-404 oktober 2013 en RFC 7159 maart 2014).
Gebruik json2.js van Douglas Crockford om deze methoden beschikbaar te maken in oude browsers zoals Internet Explorer 8.
Een eenvoudige JSON-string parseren
De methode JSON.parse()
ontleedt een tekenreeks als JSON en retourneert een primitieve JavaScript, array of object:
const array = JSON.parse('[1, 2, "c", "d", {"e": false}]');
console.log(array); // logs: [1, 2, "c", "d", {e: false}]
Een waarde serialiseren
Een JavaScript-waarde kan worden geconverteerd naar een JSON-reeks met behulp van de JSON.stringify
functie.
JSON.stringify(value[, replacer[, space]])
-
value
De waarde die moet worden geconverteerd naar een JSON-tekenreeks.
/* 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()}) // '{}'
-
replacer
Een functie die het gedrag van het stringificatieproces of een reeks String- en Number-objecten wijzigt die als witte lijst dienen voor het filteren van de eigenschappen van het waardeobject dat in de JSON-string moet worden opgenomen. Als deze waarde null is of niet wordt opgegeven, worden alle eigenschappen van het object opgenomen in de resulterende JSON-tekenreeks.
// 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
-
space
Voor leesbaarheid kan het aantal spaties dat wordt gebruikt voor inspringen worden opgegeven als de derde parameter.
JSON.stringify({x: 1, y: 1}, null, 2) // 2 space characters will be used for indentation
/* output:
{
'x': 1,
'y': 1
}
*/
Als alternatief kan een stringwaarde worden opgegeven om te gebruiken voor inspringen. Als u bijvoorbeeld '\t'
doorgeeft, wordt het tabteken gebruikt voor inspringen.
JSON.stringify({x: 1, y: 1}, null, '\t')
/* output:
{
'x': 1,
'y': 1
}
*/
Serialiseren met een vervangfunctie
Een replacer
functie kan worden gebruikt om waarden die worden geserialiseerd te filteren of te transformeren.
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)
);
Dit levert de volgende string op:
'[{"points":14,"level":31},{"points":35,"level":74},{"points":18,"level":41},{"points":15,"level":28}]'
Parsing met een reviver-functie
Een reviver-functie kan worden gebruikt om de te parseren waarde te filteren of te transformeren.
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;
});
const jsonString = '[{"name":"John","score":51},{"name":"Jack","score":17}]';
const data = JSON.parse(jsonString, (key, value) =>
key === 'name' ? value.toUpperCase() : value
);
Dit levert het volgende resultaat op:
[
{
'name': 'JOHN',
'score': 51
},
{
'name': 'JACK',
'score': 17
}
]
Dit is met name handig wanneer gegevens moeten worden verzonden die geserialiseerd / gecodeerd moeten worden wanneer ze met JSON worden verzonden, maar men wil toegang krijgen tot gedeserialiseerd / gedecodeerd. In het volgende voorbeeld werd een datum gecodeerd volgens de ISO 8601-weergave. We gebruiken de reviver-functie om dit in een JavaScript- Date
te parseren.
var jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';
var data = JSON.parse(jsonString, function (key, value) {
return (key === 'date') ? new Date(value) : value;
});
const jsonString = '{"date":"2016-01-04T23:00:00.000Z"}';
const data = JSON.parse(jsonString, (key, value) =>
key === 'date' ? new Date(value) : value
);
Het is belangrijk om ervoor te zorgen dat de reviver-functie aan het einde van elke iteratie een nuttige waarde retourneert. Als de reviverfunctie undefined
retourneert, geen waarde of de uitvoering valt tegen het einde van de functie, wordt de eigenschap uit het object verwijderd. Anders wordt de eigenschap opnieuw gedefinieerd als de retourwaarde.
Klasse-instanties serialiseren en herstellen
U kunt een aangepaste toJSON
methode en toJSON
gebruiken om instanties van uw eigen klasse in JSON te verzenden. Als een object een toJSON
methode heeft, wordt het resultaat ervan geserialiseerd in plaats van het object zelf.
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);
};
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')
});
Dit levert de string op met de volgende inhoud:
{"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;
});
Dit levert het volgende object op:
{
name: "John",
car: Car {
color: "red",
speed: "fast",
id_: 0.19349242527065402
}
}
JSON versus JavaScript-literals
JSON staat voor "JavaScript Object Notation", maar het is geen JavaScript. Zie het als een indeling voor gegevensserialisatie die toevallig direct bruikbaar is als een letterlijke JavaScript. Het is echter niet raadzaam om JSON dat rechtstreeks van een externe bron wordt opgehaald, rechtstreeks uit te voeren (dwz via eval()
). Functioneel gezien verschilt JSON niet veel van XML of YAML - enige verwarring kan worden voorkomen als JSON alleen maar wordt voorgesteld als een serialisatie-indeling die erg lijkt op JavaScript.
Hoewel de naam alleen objecten impliceert, en hoewel de meeste use-cases via een soort API altijd objecten en arrays zijn, is JSON niet alleen voor objecten of arrays. De volgende primitieve typen worden ondersteund:
- String (bijvoorbeeld
"Hello World!"
) - Nummer (bijv.
42
) - Boolean (bijv.
true
) - De waarde
null
undefined
wordt niet ondersteund in die zin dat een ongedefinieerde eigenschap bij serialisatie wordt weggelaten uit JSON. Daarom is er geen manier om JSON te deserialiseren en te eindigen met een eigenschap waarvan de waarde niet is undefined
.
De tekenreeks "42"
is geldig JSON. JSON hoeft niet altijd een buitenste envelop van "{...}"
of "[...]"
.
Hoewel nome JSON ook geldige JavaScript is en sommige JavaScript ook geldige JSON, zijn er enkele subtiele verschillen tussen beide talen en geen van beide talen is een subset van de andere.
Neem als voorbeeld de volgende JSON-string:
{"color": "blue"}
Dit kan direct in JavaScript worden ingevoegd. Het is syntactisch geldig en levert de juiste waarde op:
const skin = {"color": "blue"};
We weten echter dat "kleur" een geldige identificatienaam is en dat de aanhalingstekens rond de naam van de eigenschap kunnen worden weggelaten:
const skin = {color: "blue"};
We weten ook dat we enkele aanhalingstekens kunnen gebruiken in plaats van dubbele aanhalingstekens:
const skin = {'color': 'blue'};
Maar als we beide literals zouden nemen en ze als JSON zouden behandelen, dan is geen van beide syntactisch geldige JSON:
{color: "blue"}
{'color': 'blue'}
JSON vereist strikt dat alle eigenschapsnamen dubbel aanhalingstekens zijn en stringwaarden ook dubbel aanhalingstekens.
Het is gebruikelijk dat JSON-nieuwkomers proberen code-fragmenten te gebruiken met JavaScript-letterlijke tekens als JSON, en hun hoofd krabben over de syntaxisfouten die ze krijgen van de JSON-parser.
Er ontstaat meer verwarring wanneer onjuiste terminologie wordt toegepast in code of in gesprek.
Een veelgebruikt antipatroon is om variabelen die niet-JSON-waarden bevatten als "json" te noemen:
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.
});
In het bovenstaande voorbeeld is response.data
een JSON-tekenreeks die door een API wordt geretourneerd. JSON stopt bij het HTTP-responsdomein. De variabele met de "json" verkeerde benaming heeft slechts een JavaScript-waarde (dit kan een object, een array of zelfs een eenvoudig getal zijn!)
Een minder verwarrende manier om het bovenstaande te schrijven is:
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.
});
Ontwikkelaars neigen er ook toe om de uitdrukking "JSON-object" vaak rond te gooien. Dit leidt ook tot verwarring. Omdat zoals hierboven vermeld, een JSON-string geen object als waarde hoeft te bevatten. "JSON-string" is een betere term. Net als "XML-string" of "YAML-string". Je krijgt een string, je ontleedt hem en je krijgt een waarde.
Cyclische objectwaarden
Niet alle objecten kunnen worden geconverteerd naar een JSON-string. Wanneer een object cyclische zelfverwijzingen heeft, zal de conversie mislukken.
Dit is meestal het geval voor hiërarchische gegevensstructuren waarbij ouder en kind beide naar elkaar verwijzen:
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
Zodra het proces een cyclus detecteert, wordt de uitzondering opgeworpen. Als er geen cyclusdetectie zou zijn, zou de string oneindig lang zijn.