JSON

W tym rozdziale dowiesz się...

parse

(interpretuje: Internet Explorer 8, Firefox 3.5, Opera 10.50, Chrome)

JSON.parse(text)
JSON.parse(text, reviver)
Parametry:
String text - tekst w formacie JSON
Function reviver - funkcja przekształcająca wartości, przyjmująca argumenty:
  • String key - klucz danych albo pusty tekst
  • Object|Array|String|Boolean|Number|Null value - wartość danych
Wartość:
Object - obiekt
Array - tablica
String - tekst
Boolean - wartość logiczna
Number - liczba
Null - nic
Wyjątki:
SyntaxError - text zawiera błąd składni formatu JSON

Przekształca tekst w formacie JSON (ang. JavaScript Object Notation) na wartości proste i obiekty obsługiwane przez JavaScript. JSON jest specjalnym formatem zapisu różnych danych o typach występujących w języku JavaScript, ale z dodatkowymi ograniczeniami. Polegają one m.in. na tym, że wszystkie wartości tekstowe - w tym klucze obiektów - muszą być ujęte w znaki cudzysłowu, a nie apostrofy. Dane muszą być zapisane wprost przy pomocy literałów, a nie z użyciem operatora new oraz tworzone w całości za jednym razem bez używania zmiennych pomocniczych. Ponadto w formacie JSON można zapisać tylko następujące typy danych: Object, Array, String, Boolean, Number, Null.

Taki format zapisu danych stał się niezwykle przydatny w sytuacji, kiedy zachodzi potrzeba wymiany danych pomiędzy zdalnymi systemami, zaimplementowanymi w różnych językach. Ponieważ sposób zapisu JSON został określony standardem, w wielu językach programowania są dostępne gotowe biblioteki do jego obsługi. Dzięki temu możemy np. w skrypcie JavaScript odwołać się do aplikacji napisanej w PHP, która działa na serwerze, a następnie odczytać dane, które zostaną zwrócone z powrotem do naszego skryptu. Dzięki swojej prostocie, większej odporności na błędy oraz względnie niewielkim narzucie wydajnościowym i objętościowym, JSON w wielu miejscach wypiera XML jako uniweralny standard wymiany danych w heterogenicznym środowisku rozproszonym.

Funkcja reviver pozwala dodatkowo przekształcić dane wejściowe. Jest ona wywoływana po kolei dla wartości każdej właściwości danych wejściowych. Wartość this w tej funkcji będzie stanowił obiekt, w którym jest zapisany podany klucz. Wartość zwrócona przez funkcję jest następnie umieszczana w danych wyjściowych.

W przypadku właściwości obiektów, gdy funkcja zwrotna reviver zwróci wartość undefined albo nie zwróci nic jawnie, podany klucz zostanie usunięty z danych wyjściowych. Nie dotyczy to elementów tablic.

Przykład:

JSON.parse('{"a": 1}'); // {a: 1}
 
var x = '{"a": 1, "b": 2, "c": 3}';
var f = function (key, value) {
    if (key == "") {
        return value;
    }
    if (value < 3) {
        return value * 2;
    }
};
JSON.parse(x, f);       // {a: 2, b: 4}
 
JSON.parse("{");        // SyntaxError
JSON.parse("{a: 1}");   // SyntaxError
JSON.parse("{'a': 1}"); // SyntaxError

stringify

(interpretuje: Internet Explorer 8, Firefox 3.5, Opera 10.50, Chrome)

JSON.stringify(value)
JSON.stringify(value, replacer)
JSON.stringify(value, replacer, space)
Parametry:
Object|Array|String|Boolean|Number|Null value - dane wejściowe
Array|Function replacer - tablica zawierająca nazwy dozwolonych kluczy albo funkcja filtrująca, przyjmująca argumenty:
  • String key - klucz danych albo pusty tekst
  • Object|Array|String|Boolean|Number|Null value - wartość danych
Number|String space - wcięcie (domyślnie: "")
Wartość:
String - tekst w formacie JSON
Wyjątki:
TypeError - dane zawierają strukturę cykliczną (o nieskończonym rekurencyjnym zagnieżdżeniu)

Przekształca wartości proste i obiekty JavaScript na tekst zapisany w formacie JSON. Tak zapisane dane możemy wysłać ze skryptu np. do aplikacji napisanej w języku PHP, która pracuje na serwerze i tam poddać je dalszej obróbce.

Funkcja pomija właściwości, które nie są dostępne w pętli for-in [zobacz: Object.defineProperty - enumarable]. Wartości NaN oraz Infinity są zamieniane na null. Wartość undefined oraz typ Function również są zamieniane na null, chyba że stanowią właściwość obiektu (nie dotyczy elementów tablic) - wtedy są pomijane. W przypadku przekształcania obiektów do formatu JSON, najpierw następuje sprawdzenie, czy zadana instancja obiektu posiada metodę o nazwie toJSON. Jeżeli tak, to następuje wywołanie tej metody z bieżącą nazwą klucza danych, a zwrócona wartość jest przekształcana do formatu JSON. W innym wypadku następuje standardowe przekształcenie obiektu z pominięciem tych jego właściwości, które nie są dostępne w pętli for-in albo posiadają wartość undefined lub są typu Function.

Argument replacer pozwala dodatkowo sterować właściwościami obiektów, które pojawią się w danych wyjściowych.

  • Jeżeli replacer jest tablicą, w danych wyjściowych umieszczane są tylko te wartości, które zostały zapisane pod kluczami o nazwach w niej wymienionych. Dotyczy to wszystkich ewentualnych poziomów zagnieżdżenia.
  • Jeżeli replacer jest funkcją, jest ona wywoływana po kolei dla wartości każdej właściwości danych wejściowych. Wartość this w tej funkcji będzie stanowił obiekt, w którym jest zapisany podany klucz. Wartość zwrócona przez funkcję jest następnie umieszczana w danych wyjściowych albo pomijana (patrz wcześniejszy opis dotyczący wartości undefined).

Argument space pozwala wygenerować tekst w formie czytelniejszej dla człowieka. Kolejne klucze danych są wtedy zapisane w oddzielnych linijkach tekstu. Poza tym każda z linijek ma odpowiedni poziom wcięcia - w zależności od jej stopnia zagnieżdżenia. Przy czym długość pojedynczego wcięcia nigdy nie przekroczy 10 znaków, nawet jeśli podamy więcej.

  • Jeżeli space jest liczbą, wcięcia są wykonywane przy pomocy podanej liczby spacji.
  • Jeżeli space jest tekstem, zostanie on wprost użyty jako pojedyncze wcięcie. Nie ma tutaj ograniczenia tylko do białych znaków, jednak wcięcia wykonywane w inny sposób spowodują, że na tak wygenerowanym tekście nie będzie już można wykonać przekształcenia odwrotnego JSON.parse.

Jeżeli dane JSON są przesyłane pomiędzy dwiema aplikacjami, raczej nie ma sensu dodawać do nich wcięć. Dzięki temu będą miały mniejszą objętość, a więc zostaną przesłane szybciej.

Przykład:

JSON.stringify({a: 1});        // '{"a":1}'
var x = {a: NaN, b: Infinity, c: true, d: undefined};
JSON.stringify(x);             // '{"a":null,"b":null,"c":true}'
x = [NaN, Infinity, true, undefined]
JSON.stringify(x);             // '[null,null,true,null]'
 
x = {a: 1, b: 2, c: 3};
JSON.stringify(x, ["a", "b"]); // '{"a":1,"b":2}'
var f = function (key, value) {
    if (key == "") {
        return value;
    }
    if (value < 3) {
        return value * 2;
    }
};
x = {a: 1, b: 2, c: 3};
JSON.stringify(x, f);          // '{"a":2,"b":4}'
 
JSON.stringify(x, null, 2);    // '{\n  "a": 1,\n  "b": 2,\n  "c": 3\n}'
JSON.stringify(x, null, "\t"); // '{\n\t"a": 1,\n\t"b": 2,\n\t"c": 3\n}'
 
x.d = x;
JSON.stringify(x);             // TypeError