JSON

JSON (JavaScript Object Notation) - современный текстовый формат хранения и передачи структурированных данных в текстовом виде. Привычный объектоподобный синтаксис JSON очень удобен. Именно в этом формате данные будут приходить и отправляться на сервер, сохраняться в локальном хранилище и т. п.

Но JSON - это не объект, а его строковое представление. Ниже приведен пример JSON файла. Синтаксис похож на объект, за исключением того, что ключи это всегда строки в двойных кавычках. Строчные значения также обязательно должны быть заключены в двойные кавычки. Значениями свойств могут быть типы string, number, object, array, boolean и null.

user.json

{  "name": "Josh",  "weight": 175,  "age": 30,  "eyecolor": "brown",  "isHappy": true,  "cars": ["Chevy", "Honda"],  "favoriteBook": {    "title": "The Last Kingdom",    "author": "Bernard Cornwell",    "rating": 8.38  }}

Javascript и JSON отлично работают вместе благодаря методам встроенного класса JSON, которые преобразуют JavaScript объект в JSON и обратно. Независимо от того, что у вас есть, можно легко получить обратное.

Метод JSON.stringify()

Принимает значение и преобразовывает его в JSON. Значением может быть число, буль, null, массив или обьект. Строки это уже валидный JSON поэтому их преобразование не имеет смысла.

const dog = {  name: "Mango",  age: 3,  isHappy: true,};const dogJSON = JSON.stringify(dog);console.log(dogJSON); // "{"name":"Mango","age":3,"isHappy":true}"

Результат вызова JSON.stringify(dog) это валидный JSON (строка), который может быть сохранен в файл или передан по сети.

Не любой JavaScript объект может быть преобразован один к одному в JSON. Например, если у объекта есть методы, то при преобразовании они будут проигнорированы.

const dog = {  name: "Mango",  age: 3,  isHappy: true,  bark() {    console.log("Woof!");  },};const dogJSON = JSON.stringify(dog);console.log(dogJSON); // "{"name":"Mango","age":3,"isHappy":true}"

Также при попытке преобразовать функцию в JSON, результатом будет undefined.

JSON.stringify(() => console.log("Well, this is awkward")); // undefined

Метод JSON.parse()

Чтобы получить из JSON валидное JavaScript значение, его необходимо распарсить (parse). Это операция обратная преобразованию в строку (stringify). Теперь, когда dog это валидный объект, с ним можно работать как обычно.

const json = '{"name":"Mango","age":3,"isHappy":true}';const dog = JSON.parse(json);console.log(dog); // {name: "Mango", age: 3, isHappy: true}console.log(dog.name); // "Mango"

Обработка ошибок

Если методам класса JSON передать невалидный JSON, то они «выбросят» ошибку и весь скрипт упадёт. Для того чтобы избежать этого, используется конструкция try...catch, которая позволяет «ловить» и обрабатывать ошибки выполнения скрипта.

try {  // Code that may throw a runtime error} catch (error) {  // Error handling}
  1. Сначала выполняется код внутри блока try.

  2. Если ошибок нет, блок catch игнорируется и управление передаётся дальше.

  3. Если в блоке try произошла ошибка, его выполнение останавливается и интерпретатор переходит в блок catch.

Переменная error это объект ошибки с информацией о том, что произошло. У этого объекта есть несколько полезных свойств:

  • name - тип ошибки. Для ошибки парса это SyntaxError.

  • message - сообщение о деталях ошибки.

  • stack - стек вызовов функций на момент ошибки. Используется для отладки.

Например, парс строки приведет к такому сценарию, потому что строка с символами это не валидный JSON, так как не может быть преобразована к валидному JavaScript значению.

// Script will crash during parseconst data = JSON.parse("Well, this is awkward");console.log("❌ You won't see this log");

Используя конструкцию try...catch мы можем обработать это исключение так, чтобы скрипт продолжил работать даже в случае ошибки.

try {  const data = JSON.parse("Well, this is awkward");} catch (error) {  console.log(error.name); // "SyntaxError"  console.log(error.message); // Unexpected token W in JSON at position 0}console.log("✅ This is fine, we handled parse error in try...catch");

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

try {  const data = JSON.parse('{username: "Mango"}');} catch (error) {  console.log(error.name); // "SyntaxError"  console.log(error.message); // "Unexpected token u in JSON at position 1"}console.log("✅ This is fine, we handled parse error in try...catch");

Фазы выполнения кода

В в JavaScript код исполняется не сразу, для начала движку нужно прочитать код и узнать можно ли его вообще выполнить.

Фаза интерпретации или оценки (compile time, evaluation time) - подготовка перед исполнением кода, движок находит синтаксические ошибки, ошибки типизации и т. д. То есть код еще не выполняется, только оценивается. Если эта фаза прошла успешно, это как минимум значит, что в коде нет синтаксических ошибок и его можно запустить на исполнение.

Фаза исполнения (runtime) - скрипт начинает исполняться, выполняются инструкции вызовов функций и оценки выражений, происходит поиск необходимых идентификаторов в соответствующих областях видимости и тому подобное.

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

Попробуйте выполнить следующий код. Так как мы сделали опечатку и вместо const пытаемся объявить переменную value ключевым словом cos, на фазе компиляции будет выявлена синтаксическая ошибка и фаза исполнения даже не запустится. В консоли мы сразу увидим сообщение об ошибке.

console.log('This message will not appear in the console');cos value = 5;

try...catch ловит только ошибки которые произошли во время выполнения кода (runtime errors). Это значит, что код должен быть синтаксически правильным, иначе фаза выполнения просто не запустится. Ошибки, которые возникают во время фазы оценки, называются ошибками парсинга.

Last updated