Sök…


Introduktion

JSON (JavaScript Object Notation) är ett lätt datautbytesformat. Det är lätt för människor att läsa och skriva och enkelt för maskiner att analysera och generera. Det är viktigt att inse att JSON i JavaScript är en sträng och inte ett objekt.

En grundläggande översikt kan hittas på json.org- webbplatsen som också innehåller länkar till implementeringar av standarden på många olika programmeringsspråk.

Syntax

  • JSON.parse (input [, reviver])
  • JSON.stringify (värde [, ersättare [, utrymme]])

parametrar

Parameter detaljer
JSON.parse Analysera en JSON-sträng
input(string) JSON-sträng som ska analyseras.
reviver(function) Föreskriver en transformation för den inmatade JSON-strängen.
JSON.stringify Serialisera ett serievärde
value(string) Värde som ska serialiseras enligt JSON-specifikationen.
replacer(function eller String[] eller Number[]) Selektivt inkluderar vissa egenskaper hos value
space(String eller Number ) Om ett number tillhandahålls, kommer space på vitutrymmen att läggas till av läsbarheten. Om en string tillhandahålls kommer strängen (de första 10 tecknen) att användas som blanksteg.

Anmärkningar

Användningsmetoderna JSON standardiserades först i ECMAScript 5.1 §15.12 .

Formatet definierades formellt i applikationen / json Media Type för JSON (RFC 4627 juli 2006) som senare uppdaterades i JSON Data Interchange Format (RFC 7158 mars 2013, ECMA-404 oktober 2013 och RFC 7159 mars 2014).

För att göra dessa metoder tillgängliga i gamla webbläsare som Internet Explorer 8, använd Douglas Crockfords json2.js .

Analysera en enkel JSON-sträng

JSON.parse() analyserar en sträng som JSON och returnerar en JavaScript-primitiv, array eller objekt:

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

Serialisering av ett värde

Ett JavaScript-värde kan konverteras till en JSON-sträng med funktionen JSON.stringify .

JSON.stringify(value[, replacer[, space]])
  1. value Värdet som ska konverteras till en JSON-sträng.
/* 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 En funktion som ändrar beteendet för strängningsförfarandet eller en rad sträng- och nummerobjekt som fungerar som en vitlista för att filtrera egenskaperna för det värdeobjekt som ska inkluderas i JSON-strängen. Om detta värde är noll eller inte tillhandahålls, inkluderas alla egenskaper hos objektet i den resulterande JSON-strängen.
// 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 För läsbarhet kan antalet utrymmen som används för indragning anges som den tredje parametern.
JSON.stringify({x: 1, y: 1}, null, 2)  // 2 space characters will be used for indentation
/* output:
    {
      'x': 1,
      'y': 1
    }
*/

Alternativt kan ett strängvärde tillhandahållas för användning för indragning. Om du till exempel skickar '\t' kommer tablettecknet att användas för indragning.

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

Serialiserar med en ersättningsfunktion

En replacer kan användas för att filtrera eller omvandla värden som serialiseras.

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)
);

Detta ger följande sträng:

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

Analys med en återgivningsfunktion

En återgivningsfunktion kan användas för att filtrera eller transformera värdet som analyseras.

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
);

Detta ger följande resultat:

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

Detta är särskilt användbart när data måste skickas som måste serialiseras / kodas när de överförs med JSON, men man vill komma åt den deserialiserad / avkodad. I följande exempel kodades ett datum till dess ISO 8601-representation. Vi använder återvinningsfunktionen för att analysera detta på ett JavaScript- Date .

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
);

Det är viktigt att se till att återvinningsfunktionen returnerar ett användbart värde i slutet av varje iteration. Om återställningsfunktionen returnerar undefined , inget värde eller genomförandet faller mot slutet av funktionen raderas egenskapen från objektet. I annat fall omdefinieras egenskapen till returvärdet.

Serialisering och återställning av klassinstanser

Du kan använda en anpassad toJSON metod och återställningsfunktion för att överföra instanser av din egen klass i JSON. Om ett objekt har en toJSON metod, kommer resultatet att serialiseras istället för själva objektet.

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')
});

Detta ger en sträng med följande innehåll:

{"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;
});

Detta ger följande objekt:

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

JSON kontra JavaScript-bokstäver

JSON står för "JavaScript Object Notation", men det är inte JavaScript. Tänk på det som bara ett dataserialiseringsformat som råkar vara direkt användbart som en JavaScript-bokstav. Det är dock inte tillrådligt att direkt köra (dvs. genom eval() ) JSON som hämtas från en extern källa. Funktionellt sett skiljer sig JSON inte så mycket från XML eller YAML - viss förvirring kan undvikas om JSON bara kan föreställas som något serieringsformat som ser mycket ut som JavaScript.

Även om namnet antyder bara objekt, och även om majoriteten av användningsfallen genom någon form av API alltid råkar vara objekt och matriser, är JSON inte bara för objekt eller matriser. Följande primitiva typer stöds:

  • Sträng (t.ex. "Hello World!" )
  • Antal (t.ex. 42 )
  • Boolean (t.ex. true )
  • Värdet null

undefined stöds inte i den meningen att en odefinierad egenskap kommer att utelämnas från JSON vid serialisering. Därför finns det inget sätt att deserialisera JSON och sluta med en egendom vars värde är undefined .

Strängen "42" är giltig JSON. JSON behöver inte alltid ha ett yttre kuvert av "{...}" eller "[...]" .

Medan ingen JSON också är giltig JavaScript och vissa JavaScript också är giltiga JSON, finns det några subtila skillnader mellan båda språken och inget språk är en delmängd av det andra.

Ta följande JSON-sträng som ett exempel:

{"color": "blue"}

Detta kan sättas in direkt i JavaScript. Det är syntaktiskt giltigt och ger rätt värde:

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

Vi vet emellertid att "färg" är ett giltigt identifieringsnamn och citaten runt egendomsnamnet kan utelämnas:

const skin = {color: "blue"};

Vi vet också att vi kan använda enstaka offert istället för dubbla offerter:

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

Men om vi skulle ta båda dessa bokstäver och behandla dem som JSON, kommer ingen av dem att vara syntaktiskt giltiga JSON:

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

JSON kräver strikt att alla fastighetsnamn dubblas citeras och strängvärden också dubblas.

Det är vanligt att JSON-nykomlingar försöker använda kodutdrag med JavaScript-bokstäver som JSON och skrapar i huvudet om syntaxfelen de får från JSON-parsern.

Mer förvirring börjar uppstå när felaktig terminologi används i kod eller i konversation.

Ett vanligt antimönster är att namnge variabler som har icke-JSON-värden som "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.
});

I exemplet ovan, response.data är en JSON sträng som returneras av någon API. JSON stannar vid HTTP-svarsdomänen. Variabeln med "json" -numret har bara ett JavaScript-värde (kan vara ett objekt, en matris eller till och med ett enkelt nummer!)

Ett mindre förvirrande sätt att skriva ovan är:

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.
});

Utvecklare tenderar också att kasta uttrycket "JSON-objekt" runt mycket. Detta leder också till förvirring. Eftersom som nämnts ovan behöver en JSON-sträng inte hålla ett objekt som ett värde. "JSON-sträng" är en bättre term. Precis som "XML-sträng" eller "YAML-sträng". Du får en sträng, du analyserar den och du hamnar med ett värde.

Cykliska objektvärden

Inte alla objekt kan konverteras till en JSON-sträng. När ett objekt har cykliska självreferenser kommer konverteringen att misslyckas.

Detta är vanligtvis fallet för hierarkiska datastrukturer där förälder och barn båda refererar till varandra:

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

Så snart processen upptäcker en cykel höjs undantaget. Om det inte fanns någon cykeldetektion, skulle strängen vara oändligt lång.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow