Как форматировать JSON в JavaScript: удобочитаемый код за 5 минут
Для кого эта статья:
- Профессиональные JavaScript-разработчики
- Студенты и начинающие разработчики, желающие улучшить навыки работы с данными
Специалисты, занимающиеся проектированием и отладкой веб-приложений
Структурированные и читаемые JSON-данные — это не просто эстетика, а реальный инструмент производительности разработчика. Работа с "сырыми" JSON-объектами напоминает чтение книги без абзацев и пунктуации — технически возможно, но неоправданно мучительно. В 2024 году профессиональный JavaScript-разработчик просто обязан владеть арсеналом методов форматирования JSON — это экономит часы отладки и тонны нервных клеток. В этой статье я расскажу о проверенных техниках и инструментах, которые превращают нечитаемую JSON-кашу в структурированные данные, доступные как для машин, так и для человеческих глаз 👨💻.
Если вы стремитесь углубить свои навыки работы с данными в JavaScript, включая мастерство обработки JSON, стоит обратить внимание на курс Обучение веб-разработке от Skypro. Программа выходит за рамки базовых концепций и погружает вас в реальные сценарии обработки данных, которые встречаются в современных веб-приложениях. Помимо форматирования JSON, вы освоите полный цикл работы с данными — от получения через API до визуализации на стороне клиента.
Методы форматирования JSON через JSON.stringify()
JSON.stringify() — это базовый инструмент, который есть в арсенале каждого JavaScript-разработчика. Его основная функция — сериализация JavaScript-объектов в строку JSON. Однако далеко не все знают, что эта функция имеет мощные возможности для форматирования выходных данных.
Базовый синтаксис метода выглядит следующим образом:
JSON.stringify(value[, replacer[, space]])
Где:
- value — JavaScript-объект для преобразования
- replacer — опциональная функция или массив, определяющая, какие свойства включать в результат
- space — опциональный параметр для форматирования вывода
Именно параметр space отвечает за красоту вывода. Он может принимать число (количество пробелов для отступа) или строку (используется вместо пробелов для отступа).
Рассмотрим примеры:
const data = {
name: "John",
age: 30,
address: {
city: "New York",
street: "5th Avenue"
},
hobbies: ["programming", "reading", "hiking"]
};
// Без форматирования
console.log(JSON.stringify(data));
// {"name":"John","age":30,"address":{"city":"New York","street":"5th Avenue"},"hobbies":["programming","reading","hiking"]}
// С отступом в 2 пробела
console.log(JSON.stringify(data, null, 2));
/*
{
"name": "John",
"age": 30,
"address": {
"city": "New York",
"street": "5th Avenue"
},
"hobbies": [
"programming",
"reading",
"hiking"
]
}
*/
Можно использовать и другие символы для форматирования, например, табуляцию или даже произвольные строки:
// С табуляцией
console.log(JSON.stringify(data, null, '\t'));
// С произвольной строкой
console.log(JSON.stringify(data, null, '| '));
Параметр replacer тоже может быть полезен для форматирования. С его помощью можно фильтровать или преобразовывать определенные поля:
// Только определенные поля
console.log(JSON.stringify(data, ['name', 'age'], 2));
// С функцией замены
console.log(JSON.stringify(data, (key, value) => {
// Скрываем поля с "секретными" данными
if (key === 'street') return '***';
return value;
}, 2));
Алексей Морозов, Senior Frontend Developer
Однажды я столкнулся с интересной задачей — нужно было отображать в админ-панели сложные JSON-ответы от API с конфиденциальной информацией клиентов. Данные должны были быть читаемыми для аналитиков, но при этом определенные поля требовалось маскировать.
Сначала я пробовал создавать свою функцию фильтрации, но потом обнаружил, что всё можно сделать элегантно с помощью параметра replacer в JSON.stringify():
JSСкопировать кодfunction formatSecureJSON(data) { const sensitiveFields = ['password', 'ssn', 'creditCard']; return JSON.stringify(data, (key, value) => { if (sensitiveFields.includes(key)) { return '***HIDDEN***'; } return value; }, 2); }Этот метод не только сделал JSON читаемым, но и автоматически обеспечил безопасность данных на всех уровнях вложенности. Аналитики были в восторге от удобства чтения, а служба безопасности — от соблюдения протоколов защиты данных. И всё это — буквально в пять строк кода!

Настройка отступов и параметров в JSON.stringify()
Для достижения оптимальной читаемости JSON крайне важно правильно настроить отступы. Количество пробелов влияет не только на визуальное восприятие, но и на размер результирующей строки.
| Параметр space | Описание | Использование |
|---|---|---|
| null или undefined | Без форматирования (минификация) | Оптимально для передачи данных |
| 2 | Отступ в 2 пробела | Стандарт в большинстве проектов |
| 4 | Отступ в 4 пробела | Для улучшенной читаемости сложных структур |
| '\t' | Использование табуляции | Экономит символы при сохранении читаемости |
| '--' | Произвольный строковый отступ | Для специфических требований к форматированию |
При выборе значения параметра space нужно учитывать контекст использования. Например, для API-ответов рекомендуется минимизировать размер данных (space = null), а для отладки или вывода в пользовательский интерфейс — использовать удобочитаемый формат (space = 2 или 4).
Интересный факт: параметр space принимает числа только от 0 до 10. При значениях больше 10 будет использовано ровно 10 пробелов для отступа 🔍.
Рассмотрим более продвинутые техники форматирования с помощью параметра replacer:
const data = {
id: 1,
name: "Product",
price: 99.99,
created: new Date(),
inStock: true,
tags: ["new", "sale"],
metadata: {
version: "1.0.0",
author: "John Doe"
}
};
// Форматирование с преобразованием значений
const formattedJSON = JSON.stringify(data, (key, value) => {
// Форматирование даты
if (value instanceof Date) {
return value.toISOString();
}
// Округление чисел
if (typeof value === 'number' && !Number.isInteger(value)) {
return Number(value.toFixed(2));
}
// Преобразование булевых значений в текстовые
if (typeof value === 'boolean') {
return value ? "Да" : "Нет";
}
return value;
}, 2);
console.log(formattedJSON);
Комбинируя параметры replacer и space, можно достичь как функциональных, так и эстетических целей форматирования. Например, можно добавить дополнительную информацию к полям или изменить их представление:
// Добавление метаинформации к полям
const formattedWithMetaJSON = JSON.stringify(data, (key, value) => {
if (key === 'price') {
return { value, currency: 'USD', formattedValue: `$${value}` };
}
return value;
}, 2);
Ещё одна полезная техника — условное включение или исключение полей в зависимости от контекста:
// Исключение внутренних или служебных полей
function formatForClient(data) {
return JSON.stringify(data, (key, value) => {
// Исключаем поля, начинающиеся с "_"
if (key.startsWith('_')) return undefined;
return value;
}, 2);
}
Библиотеки для улучшенного форматирования JSON
Встроенный метод JSON.stringify() хорош для базовых задач, но когда требуется более гибкое форматирование или дополнительные возможности, стоит обратить внимание на специализированные библиотеки.
| Библиотека | Особенности | Размер (gzip) | Популярность (GitHub ⭐) |
|---|---|---|---|
| json-stringify-pretty-compact | Компактное форматирование с настройкой максимальной длины строки | ~1KB | 700+ |
| prettyjson | Цветное форматирование для терминала | ~4KB | 1.2K+ |
| json-beautify | Простое и легковесное решение | ~0.5KB | 300+ |
| jsome | Цветное форматирование с настраиваемыми темами | ~5KB | 400+ |
| jsonpack | Сжатие и форматирование JSON | ~3KB | 800+ |
Рассмотрим некоторые из этих библиотек подробнее:
1. json-stringify-pretty-compact
Эта библиотека предлагает золотую середину между минифицированным и полностью отформатированным JSON. Она умеет держать короткие массивы и объекты в одной строке, при этом используя переносы для более сложных структур.
const stringify = require('json-stringify-pretty-compact');
const formatted = stringify(data, {
indent: 2,
maxLength: 80, // Максимальная длина строки
replacer: null
});
2. prettyjson
Идеальный выбор для отображения JSON в терминале. Предлагает цветовое форматирование, делая вывод гораздо более читабельным.
const prettyjson = require('prettyjson');
// Базовое использование
console.log(prettyjson.render(data));
// Настройка стилей
const options = {
keysColor: 'rainbow',
dashColor: 'magenta',
stringColor: 'white'
};
console.log(prettyjson.render(data, options));
3. json-colorizer
Эта библиотека специализируется на цветовом оформлении JSON в браузере или терминале, что делает сложные структуры данных более понятными для визуального анализа.
const colorize = require('json-colorizer');
console.log(colorize(JSON.stringify(data, null, 2), {
colors: {
STRING_KEY: 'green',
STRING_LITERAL: 'magenta',
NUMBER_LITERAL: 'cyan'
}
}));
4. jsome
Библиотека с богатыми возможностями цветового оформления и встроенными темами.
const jsome = require('jsome');
jsome.level.show = true; // Показывать уровни вложенности
jsome.params.colored = true; // Включить цвета
jsome(data); // Выводит красиво отформатированный и цветной JSON
Дмитрий Кузнецов, Full Stack JavaScript Developer
В проекте финтех-стартапа мы столкнулись с проблемой — наш дашборд отображал транзакции пользователей в формате JSON, и клиенты жаловались на нечитаемость данных. Базовое форматирование через JSON.stringify(obj, null, 2) не решало проблему полностью — нужно было визуально выделять ключевые элементы данных.
Я начал с собственного решения, но быстро понял, что изобретаю велосипед. Тогда мы внедрили библиотеку json-colorizer, и результат превзошел ожидания. С её помощью мы:
1) Выделили разным цветом суммы транзакций и статусы 2) Сделали имена полей более заметными 3) Добавили автоматическую группировку для вложенных объектов
JSСкопировать код// Наша конфигурация для отображения финансовых данных const formattedJSON = colorize(JSON.stringify(transaction, null, 2), { colors: { STRING_KEY: '#4CAF50', // Зеленый для ключей NUMBER_LITERAL: '#FF5722', // Оранжевый для сумм STRING_LITERAL: (str) => { // Красный для отклоненных транзакций, синий для успешных return str === '"rejected"' ? '#F44336' : str === '"completed"' ? '#2196F3' : '#9E9E9E'; } } });Количество обращений в поддержку по поводу непонимания данных сократилось на 78%. А наш дизайнер даже предложил мне выпить за мое здоровье, что для нашей команды событие исключительное! 🍻
Инструменты визуализации JSON в браузере
Когда дело касается визуализации JSON прямо в браузере, существует множество инструментов — от встроенных в браузер до специальных библиотек и расширений.
Современные браузеры уже имеют встроенную поддержку красивого отображения JSON. Если открыть файл .json непосредственно в Chrome, Firefox или Edge, браузер автоматически отформатирует его для удобного просмотра.
Но для более продвинутой интеграции JSON-визуализации в веб-приложения существуют специализированные библиотеки:
- JSON Viewer — легковесная библиотека, которая преобразует JSON в интерактивное дерево с возможностью сворачивания/разворачивания узлов
- react-json-view — компонент для React с богатыми возможностями настройки и даже редактированием данных
- vue-json-pretty — аналогичное решение для экосистемы Vue
- CodeMirror — универсальный редактор кода с поддержкой подсветки синтаксиса JSON
- JSONTree — простая библиотека для отображения JSON-структур в виде дерева
Рассмотрим пример использования react-json-view для создания интерактивного просмотрщика JSON:
import React from 'react';
import ReactDOM from 'react-dom';
import ReactJson from 'react-json-view';
const MyJsonViewer = ({ data }) => {
return (
<ReactJson
src={data}
theme="monokai"
displayDataTypes={false}
collapsed={1}
enableClipboard={true}
displayObjectSize={true}
name={false}
style={{ fontFamily: 'monospace', fontSize: '14px' }}
/>
);
};
// Пример использования
ReactDOM.render(
<MyJsonViewer data={complexJsonData} />,
document.getElementById('json-container')
);
Для тех, кто предпочитает готовые решения без необходимости интеграции, существуют полезные расширения браузера:
- JSONView — популярное расширение для Chrome и Firefox
- JSON Formatter — простое расширение с минималистичным дизайном
- JSON Viewer Pro — расширенный функционал, включая поиск и фильтрацию
Для более продвинутых сценариев можно использовать Monaco Editor (тот же редактор, что используется в VS Code) для создания полноценного JSON-редактора в браузере с подсветкой синтаксиса и валидацией:
import * as monaco from 'monaco-editor';
// Создание редактора
const editor = monaco.editor.create(document.getElementById('editor-container'), {
value: JSON.stringify(data, null, 2),
language: 'json',
theme: 'vs-dark',
automaticLayout: true,
minimap: {
enabled: false
}
});
// Настройка валидации JSON
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
validate: true,
schemas: [{
uri: 'http://myserver/schema.json',
fileMatch: ['*'],
schema: {
type: 'object',
properties: {
// Описание схемы для валидации
}
}
}]
});
Ещё один интересный подход — создание кастомных рендереров JSON с использованием CSS и базового HTML, что может быть полезно для проектов с минимальными зависимостями:
function renderJSON(json, target) {
const pre = document.createElement('pre');
pre.className = 'json-container';
const formatted = JSON.stringify(json, null, 2)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
match => {
let cls = 'json-number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'json-key';
} else {
cls = 'json-string';
}
} else if (/true|false/.test(match)) {
cls = 'json-boolean';
} else if (/null/.test(match)) {
cls = 'json-null';
}
return `<span class="${cls}">${match}</span>`;
});
pre.innerHTML = formatted;
document.getElementById(target).appendChild(pre);
}
// Стили для подсветки
const styles = `
.json-container { background: #f5f5f5; padding: 1rem; border-radius: 4px; }
.json-key { color: #24292e; font-weight: bold; }
.json-string { color: #032f62; }
.json-number { color: #005cc5; }
.json-boolean { color: #e36209; }
.json-null { color: #6a737d; }
`;
// Добавление стилей
const styleElement = document.createElement('style');
styleElement.textContent = styles;
document.head.appendChild(styleElement);
Оптимизация форматирования JSON для отладки кода
Эффективное форматирование JSON особенно ценно при отладке кода. Правильно структурированные данные позволяют быстрее находить проблемы и понимать поток данных в приложении.
Вот несколько техник оптимизации JSON-форматирования специально для отладки:
- Использование console.table() для табличных данных
- Применение условного форматирования в зависимости от окружения
- Создание собственных логгеров с расширенными возможностями
- Интеграция с инструментами профилирования
Начнем с использования console.table() — это встроенный метод, который превращает массив объектов в наглядную таблицу:
// Массив объектов
const users = [
{ id: 1, name: "John", age: 30, role: "admin" },
{ id: 2, name: "Alice", age: 25, role: "user" },
{ id: 3, name: "Bob", age: 35, role: "editor" }
];
// Обычный вывод
console.log("Users:", users);
// Табличный вывод
console.table(users);
// Можно даже выбрать колонки
console.table(users, ["name", "role"]);
Часто полезно создавать различные уровни детализации форматирования в зависимости от окружения:
function logJSON(data, level = 'info') {
const isDev = process.env.NODE_ENV === 'development';
// В продакшене – минимальное форматирование
if (!isDev) {
console.log(JSON.stringify(data));
return;
}
// В разработке – подробное форматирование с цветами
switch(level) {
case 'error':
console.error('%c JSON Error:', 'color: red; font-weight: bold', JSON.stringify(data, null, 2));
break;
case 'warning':
console.warn('%c JSON Warning:', 'color: orange; font-weight: bold', JSON.stringify(data, null, 2));
break;
case 'info':
default:
console.log('%c JSON Info:', 'color: blue; font-weight: bold', JSON.stringify(data, null, 2));
}
}
Для более сложных сценариев отладки можно создать специализированный логгер с фильтрацией и поиском по данным:
class JSONDebugger {
constructor(options = {}) {
this.options = {
maxDepth: 3,
maxArrayLength: 100,
...options
};
}
log(data, label = '') {
console.group(label || 'JSON Debug');
console.log(this.format(data));
console.groupEnd();
}
format(data, depth = 0) {
if (depth >= this.options.maxDepth) {
return '[Max Depth Reached]';
}
if (Array.isArray(data)) {
if (data.length > this.options.maxArrayLength) {
const shown = data.slice(0, this.options.maxArrayLength);
return [...shown.map(item => this.format(item, depth + 1)), `... ${data.length – shown.length} more items`];
}
return data.map(item => this.format(item, depth + 1));
}
if (data !== null && typeof data === 'object') {
const formatted = {};
for (const [key, value] of Object.entries(data)) {
formatted[key] = this.format(value, depth + 1);
}
return formatted;
}
return data;
}
search(data, query) {
const results = [];
this.findInObject(data, query, [], results);
console.group(`Search Results for: "${query}"`);
if (results.length === 0) {
console.log('No matches found');
} else {
results.forEach((result, i) => {
console.log(`Match #${i+1}: Path: ${result.path.join('.')}`);
console.log(result.value);
});
}
console.groupEnd();
}
findInObject(obj, query, path, results) {
if (obj === null || typeof obj !== 'object') {
if (String(obj).includes(query)) {
results.push({ path: [...path], value: obj });
}
return;
}
for (const [key, value] of Object.entries(obj)) {
const newPath = [...path, key];
// Поиск в ключах
if (key.includes(query)) {
results.push({ path: newPath, value });
}
// Рекурсивный поиск в значениях
this.findInObject(value, query, newPath, results);
}
}
}
// Использование
const debugger = new JSONDebugger({ maxDepth: 5 });
debugger.log(complexData, 'API Response');
debugger.search(complexData, 'error');
Интеграция с инструментами профилирования позволяет оценить влияние форматирования на производительность:
function benchmarkJSONFormatting(data, iterations = 1000) {
console.log(`Benchmark for ${iterations} iterations:`);
// Тест 1: Без форматирования
console.time('No formatting');
for (let i = 0; i < iterations; i++) {
JSON.stringify(data);
}
console.timeEnd('No formatting');
// Тест 2: С базовым форматированием
console.time('Basic formatting (2 spaces)');
for (let i = 0; i < iterations; i++) {
JSON.stringify(data, null, 2);
}
console.timeEnd('Basic formatting (2 spaces)');
// Тест 3: С продвинутым форматированием и replacer
console.time('Advanced formatting with replacer');
for (let i = 0; i < iterations; i++) {
JSON.stringify(data, (key, value) => {
if (value instanceof Date) return value.toISOString();
return value;
}, 2);
}
console.timeEnd('Advanced formatting with replacer');
}
// Запуск бенчмарка
benchmarkJSONFormatting(largeDataObject);
Для диагностики проблем с большими JSON-структурами полезна функция "diff" — сравнение двух JSON-объектов:
function jsonDiff(obj1, obj2) {
const changes = {
added: {},
removed: {},
modified: {}
};
// Поиск добавленных и измененных
for (const key in obj2) {
if (!obj1.hasOwnProperty(key)) {
changes.added[key] = obj2[key];
} else if (JSON.stringify(obj1[key]) !== JSON.stringify(obj2[key])) {
changes.modified[key] = {
from: obj1[key],
to: obj2[key]
};
}
}
// Поиск удаленных
for (const key in obj1) {
if (!obj2.hasOwnProperty(key)) {
changes.removed[key] = obj1[key];
}
}
return changes;
}
// Использование
const before = { name: "Product", price: 10, features: ["A", "B"] };
const after = { name: "Product Premium", price: 15, features: ["A", "B", "C"] };
console.log("Changes:", jsonDiff(before, after));
Все эти методы помогут значительно упростить отладку приложений, работающих с JSON-данными, и сделать процесс разработки более эффективным 🛠️.
Изящное форматирование JSON — это не просто косметическая опция, а необходимый элемент инструментария современного JavaScript-разработчика. От базовых настроек JSON.stringify() до специализированных библиотек визуализации — теперь у вас есть полный арсенал средств для превращения неструктурированных данных в читаемый, доступный для анализа формат. Особенно важно помнить о контексте: для передачи данных по сети минифицируйте JSON, для отладки используйте детальное форматирование с отступами, а для пользовательского интерфейса применяйте интерактивные визуализации. Мастерство работы с JSON напрямую влияет на скорость разработки и качество конечного продукта — инвестиции в эти навыки всегда окупаются сторицей.