Работа с JSON в JavaScript: парсинг и сериализация данных

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в JSON и его роль в JavaScript

JSON (JavaScript Object Notation) — это легковесный формат обмена данными, основанный на синтаксисе объектов JavaScript. Несмотря на своё происхождение, JSON стал универсальным стандартом для передачи структурированных данных между сервером и клиентом, а также для хранения конфигураций и обмена информацией в микросервисных архитектурах.

В среде Node.js работа с JSON является повседневной задачей: от чтения конфигурационных файлов до обработки ответов REST API. В этой статье мы подробно рассмотрим два ключевых метода — JSON.parse() и JSON.stringify(), а также разберём типичные ошибки и лучшие практики.

1. Парсинг JSON: метод JSON.parse()

Метод JSON.parse() преобразует строку в формате JSON в объект JavaScript. Это необходимо, когда вы получаете данные от сервера, из файла или из внешнего источника.

Базовый синтаксис

const jsonString = '{"name": "Анна", "age": 30, "isStudent": false}';
const user = JSON.parse(jsonString);
console.log(user.name); // "Анна"
console.log(user.age);  // 30

Продвинутое использование: reviver-функция

Вторым аргументом JSON.parse() может принимать функцию-преобразователь (reviver), которая позволяет модифицировать значения в процессе парсинга. Это полезно для конвертации строковых дат в объекты Date или для валидации данных.

const jsonData = '{"date": "2024-01-15T10:30:00.000Z", "value": 42}';
const parsed = JSON.parse(jsonData, (key, value) => {
  if (key === 'date') {
    return new Date(value);
  }
  return value;
});
console.log(parsed.date instanceof Date); // true
console.log(parsed.date.toLocaleDateString()); // "15.01.2024"

Обработка ошибок парсинга

Некорректный JSON вызовет исключение SyntaxError. Всегда оборачивайте вызов JSON.parse() в блок try...catch:

function safeParse(jsonString) {
  try {
    return { data: JSON.parse(jsonString), error: null };
  } catch (error) {
    console.error('Ошибка парсинга JSON:', error.message);
    return { data: null, error: error.message };
  }
}

const result = safeParse('{"name": "Ошибка"}');
console.log(result.data.name); // "Ошибка"

2. Сериализация в JSON: метод JSON.stringify()

Метод JSON.stringify() выполняет обратную задачу — преобразует объект JavaScript в строку JSON. Это используется при отправке данных на сервер, сохранении состояния или логировании.

Базовый синтаксис

const user = {
  name: 'Иван',
  age: 25,
  skills: ['JavaScript', 'Node.js']
};

const jsonString = JSON.stringify(user);
console.log(jsonString);
// {"name":"Иван","age":25,"skills":["JavaScript","Node.js"]}

Параметры форматирования

Третий аргумент JSON.stringify() позволяет задать отступы для читаемого вывода. Это особенно полезно при записи в файлы или отладке.

const config = {
  server: { port: 3000, host: 'localhost' },
  database: { host: 'db.example.com', port: 5432 }
};

// Компактный вывод
console.log(JSON.stringify(config));

// Читаемый вывод с отступами в 2 пробела
console.log(JSON.stringify(config, null, 2));
// {
//   "server": {
//     "port": 3000,
//     "host": "localhost"
//   },
//   ...
// }

Фильтрация свойств с помощью replacer

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

const user = {
  id: 1,
  name: 'Мария',
  email: 'maria@example.com',
  password: 'secret123',
  role: 'admin'
};

// Исключаем конфиденциальные данные
const safeUser = JSON.stringify(user, ['id', 'name', 'email', 'role']);
console.log(safeUser);
// {"id":1,"name":"Мария","email":"maria@example.com","role":"admin"}

// Или с помощью функции-фильтра
const filteredUser = JSON.stringify(user, (key, value) => {
  if (key === 'password') return undefined; // исключаем
  return value;
});

3. Работа с JSON в файловой системе Node.js

В Node.js часто требуется читать и записывать JSON-файлы. Рассмотрим типичные сценарии.

Чтение JSON из файла

const fs = require('fs');
const path = require('path');

function readJSONFile(filePath) {
  try {
    const absolutePath = path.resolve(filePath);
    const fileContent = fs.readFileSync(absolutePath, 'utf-8');
    return JSON.parse(fileContent);
  } catch (error) {
    if (error.code === 'ENOENT') {
      console.error('Файл не найден:', filePath);
    } else {
      console.error('Ошибка чтения JSON:', error.message);
    }
    return null;
  }
}

const config = readJSONFile('./config.json');
console.log(config?.database?.host);

Запись JSON в файл

function writeJSONFile(filePath, data) {
  try {
    const jsonString = JSON.stringify(data, null, 2);
    fs.writeFileSync(filePath, jsonString, 'utf-8');
    console.log('Данные успешно записаны в файл:', filePath);
  } catch (error) {
    console.error('Ошибка записи JSON:', error.message);
  }
}

const appSettings = {
  appName: 'MyApp',
  version: '1.0.0',
  features: ['auth', 'api', 'logging']
};

writeJSONFile('./settings.json', appSettings);

Асинхронная работа с JSON

const fsPromises = require('fs').promises;

async function readJSONAsync(filePath) {
  try {
    const content = await fsPromises.readFile(filePath, 'utf-8');
    return JSON.parse(content);
  } catch (error) {
    console.error('Асинхронная ошибка:', error.message);
    throw error;
  }
}

// Использование
(async () => {
  try {
    const data = await readJSONAsync('./data.json');
    console.log('Загружено записей:', Object.keys(data).length);
  } catch (err) {
    // обработка
  }
})();

4. Типичные ошибки и их решение

Ошибка: Unexpected token

Возникает, когда строка содержит невалидный JSON. Частые причины: одинарные кавычки вместо двойных,

Блоги

Рекомендаций по книгам