Формат JSON

Формат JSON

Здравствуйте!  В этом уроке я расскажу про работу  с форматом JSON, который используется как  для представления объектов в виде строки,  так и для обмена данными между клиентом и сервером,  используя технологию AJAX.

Надо отметить, что JSON один из наиболее удобных форматов  данных и именно он используется при клиент-серверном взаимодействии ранее использовался XML, но он был сложен при разборе данных поэтому не получил такого широкого  распространения и ему на смену пришел JSON.

Все современные браузеры поддерживают работу с JSON и для этого у них имеются встроенные методы о них мы и поговорим в этой статье.

формат json

Формат JSON

Данные в формате JSON, сокращенно от (JavaScript Object Notification)  представляют собой:

  • JavaScript-объекты { … } или
  • Массивы [ … ] или
  • Значения одного из типов:
    • строки в двойных  кавычках,
    • число,
    • логическое значение true/false,
    • null.

Почти все языки программирования имеют функции для преобразования объектов в формат JSON.

Основные методы для работы с JSON в языке JavaScript – это:

  • JSON.parse – читает объекты из строки в формате JSON.
  • JSON.stringify – превращает объекты в строку в формате JSON, используется, когда нужно из JavaScript передать данные по сети на сервер.

Метод JSON.parse

Вызов JSON.parse(str) превратит строку с данными в формате JSON в JavaScript-объект/массив/значение.

Например:

var nums = "[0, 1, 2, 3, 4]"; 
nums = JSON.parse(numbers); 
alert( nums[2] ); // 2

Или так:

var user = '{ "name": "Вася", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }'; 
user = JSON.parse(user); 
alert( user.friends[2] ); // 2

Данные могут быть сколь угодно сложными, объекты и массивы могут включать в себя другие объекты и массивы. Главное, чтобы они соответствовали формату.

JSON-объекты ≠ JavaScript-объекты

Объекты в формате JSON похожи на обычные JavaScript-объекты, но  главное отличие строки – они должны быть именно в двойных кавычках.

Так, первые 2 свойства объекта ниже – некорректны:

                     
      { name: "Вася", // ошибка: ключ name без кавычек! 
       "surname": 'Иванов',// ошибка: одинарные кавычки у значения 'Иванов'! 
       "age": 35, // .. а тут всё в правильно. 
       "isAdmin": false // и тут тоже всё правильно}

Кроме того, в формате JSON не поддерживаются комментарии. Он предназначен только лишь для передачи данных.

Читайте также  Объекты. Как создать объект в JavaScript.

Умный разбор: JSON.parse(str, reviver)

Метод JSON.parse поддерживает и более сложные алгоритмы разбора.

Например, если мы получили с сервера объект с данными события event.

Он выглядит так:

// title: название события, 
date: дата события 
var str = '{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"}';

И теперь нужно восстановить его, то есть превратить в обычный JavaScript-объект.
Попробуем вызвать для этого метод JSON.parse:

var str = '{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"}'; 
   var event = JSON.parse(str); 
  alert( event.date.getDate() ); // ошибка!

Но увы, ошибка!

Дело в том, что значением event.date является строка, а отнюдь не объект Date. Откуда  методу JSON.parse знать, что нужно превратить строку именно в дату?

Для восстановления из строки у JSON.parse(str, reviver) есть второй параметр reviver, который является функцией function(key, value).

Если она будет указана, то в процессе чтения объекта из строки JSON.parse передаёт ей по очереди все создаваемые пары ключ-значение и может возвратить либо преобразованное значение, либо undefined, в случае если его нужно пропустить.

В данном случае нам надо создать правило, что ключ date всегда будет означать дату:

// дата в строке - в формате UTC 
var str = '{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"}'; 
var event = JSON.parse(str, function(key, value) { 
if (key == 'date') return new Date(value); 
return value; }); 
alert( event.date.getDate() ); // теперь сработает!

Кстати, эта возможность работает и также для вложенных объектов тоже:

var schedule = `{ 
  "events": [ 
    {"title":"Конференция","date":"2014-11-30T12:00:00.000Z"}, 
    {"title":"День рождения","date":"2015-04-18T12:00:00.000Z"} 
  ]
}`; 
schedule = JSON.parse(schedule, function(key, value) { 
if (key == 'date') return new Date(value); 
 return value; }); 
alert( schedule.events[1].date.getDate() ); // сработает!

Сериализация, метод JSON.stringify

Метод JSON.stringify(value, replacer, space) преобразует или  «сериализует»  значение в JSON-строку.

Давайте рассмотрим пример использования:

var event = { title: "Конференция", data: "сегодня" }; 
var str = JSON.stringify(event); alert( str ); 
// {"title":"Конференция","datа":"сегодня"} 
// Обратное преобразование. event = JSON.parse(str);

При сериализации объекта будет вызван его метод toJSON.

Читайте также  Создание объектов через оператор "new"

Если такого метода нет, то перечисляются его свойства, кроме функций.

Посмотрим это в примере:

var room = { number: 23, occupy: function() { alert( this.number ); } }; 
var event = { title: "Конференция", date: new Date(Date.UTC(2014, 0, 1)), room: room }; 
alert( JSON.stringify(event) ); /*
  {
    "title":"Конференция",
    "date":"2014-01-01T00:00:00.000Z",  // (1)
    "room": {"number":23}               // (2)
  }
*/

Обратите внимание на 2 момента:

  1. Дата превратилась в строку. Это не случайно: у всех дат есть встроенный метод toJSON. Его результат в данном случае – строка в часовом поясе UTC.
  2. У объекта room нет метода toJSON. Поэтому он сериализуется перечислением свойств. Мы, конечно, могли бы добавить такой метод, тогда в итог попал бы его результат:
    var room = { number: 23, toJSON: function() { return this.number; } }; 
    alert( JSON.stringify(room) ); // 23
    

Исключение свойств

Попытаемся преобразовать в JSON объект, содержащий ссылку на DOM.

Например:

var user = { name: "Вася", age: 25, window: window }; 
alert( JSON.stringify(user) ); 
// ошибка! // TypeError: Converting circular structure to JSON (текст из Chrome)

Произошла ошибка! В чём же дело? Неужели некоторые объекты запрещены? Как видно из текста ошибки – дело совсем в другом. Глобальный объект window – сложная структура с кучей встроенных свойств и круговыми ссылками, поэтому его преобразовать невозможно. Да и надо ли?
Во 2-м параметре JSON.stringify(value, replacer) можно указать массив свойств, которые подлежат сериализации.
Например:

var user = { name: "Вася", age: 25, window: window }; 
alert( JSON.stringify(user, ["name", "age"]) ); 
// {"name":"Вася","age":25}

Для более сложных ситуаций вторым параметром можно передать функцию function(key, value), которая возвращает сериализованное value либо undefined, если его не нужно включать в результат:

var user = { name: "Вася", age: 25, window: window }; 
var str = JSON.stringify(user, function(key, value) { 
if (key == 'window') return undefined; return value; }); 
alert( str ); 
// {"name":"Вася","age":25}

В примере выше функция пропустит свойство с названием window. Для остальных она просто вернет значение, передавая его алгоритму. А могла бы и как-то обработать.

Функция replacer работает рекурсивно

То есть, если объект содержит вложенные объекты, массивы и т.д., то все они пройдут через replacer.

Читайте также  Перебор свойств в объектах

Красивое форматирование

В методе JSON.stringify(value, replacer, space) есть ещё 3-ий параметр space.
Если он является числом – то уровни вложенности в JSON оформляются указанным количеством пробелов, а если строкой – вставляется эта строка.
Например:

var user = { name: "Вася", age: 25, roles: { isAdmin: false, isEditor: true } }; 
var str = JSON.stringify(user, "", 4); 
alert( str ); /* Результат -- красиво сериализованный объект:
{
    "name": "Вася",
    "age": 25,
    "roles": {
        "isAdmin": false,
        "isEditor": true
    }
}
*/

Итого

  • JSON – это формат для представления объектов в виде строки.
  • Методы JSON.parse и JSON.stringify позволяют о преобразовать объект в строку и обратно.

Задания

Преобразуйте объект в JSON

Превратите объект lead из примера ниже в JSON:

var lead = { name: "Василий Петрович", age: 45 };

После этого прочитайте строку обратно в объект.

Преобразуйте объекты со ссылками в JSON

Преобразуйте объект komanda из примера ниже в JSON:

var leader = { name: "Василий Петрович" }; 
var soldier = { name: "Ванька" }; 
// эти объекты ссылаются друг на друга! 
leader.soldier = soldier; soldier.leader = leader; 
var komanda = [leader, soldier];

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Поделиться

Об авторе

admin administrator

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: