JSON и методы работы с ним

JSON (расшифровывается как JavaScript Object Notation) – текстовый формат репрезентации объектов и значений, разработанный и внедренный Дугласом Крокфордом. Он принадлежит к числу форматов, используемых для обмена данными, и отличается от других распространенных форматов (например, своего прародителя – YAML, а также XML) большей простотой и компактностью, что способствует его все более широкому распространению.

Формат JSON и его особенности

Для описания формата был создан стандарт RFC 4627. Хотя формат произошел от JS и изначально был заточен под работу с ним, со временем библиотеки, способные взаимодействовать с JSON, стали появляться в ряде других языков, и сейчас его принято считать не привязанным к языку. Его часто применяют для обмена данными, если клиентская часть работает с JS, а серверная пишется, к примеру, на PHP или Ruby.

Популяризация JSON связана со следующими преимуществами:

  1. Компактность и лаконичность кода, что особенно полезно при обмене данными – так они загружаются быстрее, чем при представлении в более громоздких форматах. Особенность связана с минимизацией форматирования: при создании кода задействуется малое число специальных знаков.
  2. Простота структуры данных и легкость чтения.
  3. Удобные методы, реализующие превращение объекта JS в строку формата и наоборот. для выполнения первой операции используется метод JSON.stringify, для второй – JSON.parse (поэтому сам процесс еще называют парсингом).

Сравнение с YAML и XML

Формат является подмножеством YAML как с точки зрения синтаксиса, так и в плане функций. В версии 1.2 родительского формата указывается, что всякий файл JSON может адекватно читаться и в YAML (в более ранних версиях спецификации перекрывались не целиком). Как главное различие стоит выделить синтаксические расширения YAML, пока что не поддерживаемые дочерним форматом:

  • работа с расширяемыми типами данных, не являющимися примитивами;
  • возможность создавать ссылки на якоря и выражать этим способом рекурсию;
  • использование блоков с отступами как элементов синтаксиса (способ описать структуру с минимумом знаков).

По сравнению с XML, JSON обладает рядом преимуществ: простотой синтаксиса, меньшим размером кода, удобными методами. Этим и объясняется постепенное вытеснение XML новым форматом. Широкое распространение получает JSON Schema – способ описания структуры файла, разработанный по аналогии с XML Schema. Также JSON часто выбирают при работе с архитектурой REST, используемой при создании ПО для территориально распределенных систем.

Одно из отличий JSON от обоих упомянутых языков – организация данных в нем такая же, как в привычных JS-объектах. Но не для всякого объекта можно создать полностью идентичную структуру формата JSON. К примеру, когда объект включает в себя методы, при трансформации в строчный формат они игнорируются и не попадают в JSON.

Строка и ее структура

Информация в формате JSON представляется в виде строк. Для получения доступа к данным строки нужно трансформировать в JS-объекты. Сделать это несложно: в языке существует глобальный объект, имеющий методы для такой трансформации. Он так и называется – JSON.

Переход строчной формы данных в объектную называют десериализацией, а обратный процесс, оптимизированный для передачи по сети – сериализацией (она подразумевает переход параллельно представленных данных в последовательные). Объект можно сохранить в текстовом файле .json. Методов этот формат не включает, он подразумевает лишь перечисление свойств.

Строение строки во многом сходно с таковым объекта JS. Она тоже включает в себя пары, состоящие из ключа и его значения. При этом на типы данных и способы их записи накладываются определенные ограничения:

  1. Ключ должен принадлежать к типу данных string. От значения он отделяется двоеточием.
  2. Для значения допустимы большинство привычных типов данных. Помимо string, к ним принадлежат булевская переменная, число, массив любого уровня вложенности, объект (типа JSON), а также специальный тип null. Остальные варианты (в том числе функции и календарные даты) использовать не полагается. Это одно из отличий данного формата от объектов.
  3. Большое значение имеет соблюдение норм синтаксиса с правильной расстановкой кавычек. Если им пренебрегать, доступ к данным получен не будет. Как все ключи, так и их значения необходимо заключать в двойные (не одинарные!) кавычки. Исключение допускается делать для чисел, null, а также булевских переменных true и false. Если при записи объектов пренебрегать кавычками для ключей допустимо, то при работе с JSON одна ошибка (отсутствие закрывающей, открывающей кавычки либо использование одинарных) может привести к инвалидности файла.
  4. При записи значения после закрывающей кавычки ставится запятая. Следующая пара «ключ-значение» задается с новой строки.
  5. Комментарии в структуре файла использовать нельзя.

Вот пример корректной записи такого формата:

var json = ‘{
«name»: «Софья»,
«age»: 30,
«marriage»: true,
«arr»: [1, 2, 3, 4],
}’;

А вот эта запись содержит ошибки:

var json = ‘{
name: «Софья»,
«age»: ’30’,
}’;

В первой строке ключ name не заключен в кавычки. Во второй строке использовано некорректное написание кавычек (одинарные вместо двойных) для значения возраста. Проверить корректность синтаксиса можно программой JSON Lint.

Строка JSON может состоять из данных различных типов, например:

{
«name»: «Софья»,
«age»: 30,
«father»: {
«name»: «Олег»,
«age»: 68
},
«children»: [
«Алексей»,
«Илья»],
«married»: true,
«cat»: null
}

Здесь значение ключа имени представлено строкой (типом string), возраста – числом, ключа “father” – объектом, содержащим информацию об имени и возрасте отца. Ключ “children” имеет значение в виде массива из двух элементов, ключ “married” – в виде булевской переменной, а “cat” – null.

Использование формата в веб-разработке

Один из самых распространенных примеров использования JSON – передача серверных данных браузеру (клиентской части) при реализации запроса AJAX. Этот процесс проходит в два этапа. Сначала сервер, получив клиентский запрос, подготавливает данные в формате, легко заносящемся в строки JSON, формирует соответствующий файл и отправляет его клиенту.

На втором этапе происходит распаковка полученных клиентом данных: строчки JSON переводятся в традиционные объекты JS. Затем клиент может выполнять с ними нужные операции (к примеру, вывод на веб-страницу).

Традиционные операции с форматом включают в себя превращение данных строчек в JS-объекты и обратное действие – представление объектов в виде строк. Пример их работы можно показать, создав переменную personalInfo, содержащую JSON-строку, куда занесены личные данные женщины из примера выше:

var personalInfo = ‘{«name»: «Софья», «age»: 30, «father»: {«name»: «Олег», «age»: 68}, «children»: [«Алексей», «Илья»],»married»: true, «cat»: null}’;

Парсинг JSON

Этим термином называется превращение строки данного формата в стандартный JS-объект. Сделать это можно посредством двух методов – parse и eval. Однако второй из них применять в реальных проектах не рекомендуется: это снижает безопасность.

Если кто-то внедрит в JSON-строчку вредоносный скрипт, он будет успешно выполнен, что может привести к непредсказуемым последствиям. Поэтому лучше задействовать метод JSON.parse, не создающий подобных брешей. Для примера с переменной personalInfo его реализация будет выглядеть так:

var personal = JSON.parse(personalInfo);

Здесь переменная personal будет представлять собой JS-объект, созданный в результате парсинга JSON-строки. Превращение в объект посредством метода eval реализуется так:

var personal = eval(‘(‘+personalInfo+’)’);

Конвертирование объекта JavaScript в строку JSON

Для такой операции используется метод JSON.stringify. Его код может выглядеть так:

var personalString = JSON.stringify(personal);

Ниже приводится вариант преобразования данных женщины посредством этого метода:

let data = {
«name»: «Софья»,
«age»: 30,
«father»: {
«name»: «Олег»,
«age»: 68
},
«children»: [
«Алексей»,
«Илья»],
«married»: true,
«cat»: null
}
let json = JSON.stringify(data);
alert(typeof json);

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

alert(json);

В результате личные данные человека будут выведены в форме JSON-структуры:

{
«name»: «Софья»,
«age»: 30,
«father»: {
«name»: «Олег»,
«age»: 68
},
«children»: [
«Алексей»,
«Илья»],
«married»: true,
«cat»: null
}

Такую структуру, полученную с использованием этого метода, принято называть сериализованным объектом. Его можно передать по сети или разместить в хранилище. Разные типы данных в формате представляются по-разному. Например, числа и булевские переменные выводятся в своем неизменном виде:

alert( JSON.stringify(5) ) — в результате будет выведено число 5;
alert( JSON.stringify(false) ) – выводится false.

Тексты при преобразовании в JSON заключаются в двойные кавычки:

alert( JSON.stringify(‘text’) ) // «text»

В силу независимости формата от языка при реализации метода stringify некоторые характеристики JS-объектов игнорируются и не попадают в получающуюся строку. К ним, помимо методов, относятся символьные свойства, а также те, где в значении стоит undefined.

При работе со stringify нельзя использовать циклические ссылки. Вот пример нарушения этого правила:

let cabinet = {
number: 20
};

let gathering = {
title: “Session”,
participants: [“Christine”, “Marie”]
};

gathering.place = cabinet;
cabinet.occupiedBy = gathering;

JSON.stringify(gathering);

Последняя строка в приведенном коде описывает некорректное действие – попытку трансформировать в JSON структуру с циклическими ссылками. В этой структуре gathering.place ссылается на cabinet, а cabinet.occupiedBy – на gathering.

Метод toJSON

Этот метод внедряют в объекты для того, чтобы превращать их в строки. При вызове метода stringify для такого объекта будет возвращаться строка с его данными. На практике это выглядит так:

let cabinet = {
number: 20,
toJSON() {
return this.number;
}
};

let gathering = {
title: “Session”,
cabinet
};

alert( JSON.stringify(cabinet) );
alert( JSON.stringify(gathering) );

Первая из двух строк alert вызывает непосредственно объект, в который был внедрен toJSON, и возвращает свойство, прописанное в коде (число 20). Вторая строка вызывает второй из сериализируемых объектов, и получившаяся строка будет выглядеть так:

{
“title”: “Session”,
“cabinet”: 20
}

Таким образом, вызываются не только заданные характеристики объекта, но и номер связанного с ним кабинета.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *