Как форматировать JSON в JavaScript: удобочитаемый код за 5 минут

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Профессиональные JavaScript-разработчики
  • Студенты и начинающие разработчики, желающие улучшить навыки работы с данными
  • Специалисты, занимающиеся проектированием и отладкой веб-приложений

    Структурированные и читаемые JSON-данные — это не просто эстетика, а реальный инструмент производительности разработчика. Работа с "сырыми" JSON-объектами напоминает чтение книги без абзацев и пунктуации — технически возможно, но неоправданно мучительно. В 2024 году профессиональный JavaScript-разработчик просто обязан владеть арсеналом методов форматирования JSON — это экономит часы отладки и тонны нервных клеток. В этой статье я расскажу о проверенных техниках и инструментах, которые превращают нечитаемую JSON-кашу в структурированные данные, доступные как для машин, так и для человеческих глаз 👨‍💻.

Если вы стремитесь углубить свои навыки работы с данными в JavaScript, включая мастерство обработки JSON, стоит обратить внимание на курс Обучение веб-разработке от Skypro. Программа выходит за рамки базовых концепций и погружает вас в реальные сценарии обработки данных, которые встречаются в современных веб-приложениях. Помимо форматирования JSON, вы освоите полный цикл работы с данными — от получения через API до визуализации на стороне клиента.

Методы форматирования JSON через JSON.stringify()

JSON.stringify() — это базовый инструмент, который есть в арсенале каждого JavaScript-разработчика. Его основная функция — сериализация JavaScript-объектов в строку JSON. Однако далеко не все знают, что эта функция имеет мощные возможности для форматирования выходных данных.

Базовый синтаксис метода выглядит следующим образом:

JS
Скопировать код
JSON.stringify(value[, replacer[, space]])

Где:

  • value — JavaScript-объект для преобразования
  • replacer — опциональная функция или массив, определяющая, какие свойства включать в результат
  • space — опциональный параметр для форматирования вывода

Именно параметр space отвечает за красоту вывода. Он может принимать число (количество пробелов для отступа) или строку (используется вместо пробелов для отступа).

Рассмотрим примеры:

JS
Скопировать код
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"
]
}
*/

Можно использовать и другие символы для форматирования, например, табуляцию или даже произвольные строки:

JS
Скопировать код
// С табуляцией
console.log(JSON.stringify(data, null, '\t'));

// С произвольной строкой
console.log(JSON.stringify(data, null, '| '));

Параметр replacer тоже может быть полезен для форматирования. С его помощью можно фильтровать или преобразовывать определенные поля:

JS
Скопировать код
// Только определенные поля
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:

JS
Скопировать код
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, можно достичь как функциональных, так и эстетических целей форматирования. Например, можно добавить дополнительную информацию к полям или изменить их представление:

JS
Скопировать код
// Добавление метаинформации к полям
const formattedWithMetaJSON = JSON.stringify(data, (key, value) => {
if (key === 'price') {
return { value, currency: 'USD', formattedValue: `$${value}` };
}
return value;
}, 2);

Ещё одна полезная техника — условное включение или исключение полей в зависимости от контекста:

JS
Скопировать код
// Исключение внутренних или служебных полей
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. Она умеет держать короткие массивы и объекты в одной строке, при этом используя переносы для более сложных структур.

JS
Скопировать код
const stringify = require('json-stringify-pretty-compact');

const formatted = stringify(data, {
indent: 2,
maxLength: 80, // Максимальная длина строки
replacer: null
});

2. prettyjson

Идеальный выбор для отображения JSON в терминале. Предлагает цветовое форматирование, делая вывод гораздо более читабельным.

JS
Скопировать код
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 в браузере или терминале, что делает сложные структуры данных более понятными для визуального анализа.

JS
Скопировать код
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

Библиотека с богатыми возможностями цветового оформления и встроенными темами.

JS
Скопировать код
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:

JS
Скопировать код
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-редактора в браузере с подсветкой синтаксиса и валидацией:

JS
Скопировать код
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, что может быть полезно для проектов с минимальными зависимостями:

JS
Скопировать код
function renderJSON(json, target) {
const pre = document.createElement('pre');
pre.className = 'json-container';

const formatted = JSON.stringify(json, null, 2)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.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-форматирования специально для отладки:

  1. Использование console.table() для табличных данных
  2. Применение условного форматирования в зависимости от окружения
  3. Создание собственных логгеров с расширенными возможностями
  4. Интеграция с инструментами профилирования

Начнем с использования console.table() — это встроенный метод, который превращает массив объектов в наглядную таблицу:

JS
Скопировать код
// Массив объектов
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"]);

Часто полезно создавать различные уровни детализации форматирования в зависимости от окружения:

JS
Скопировать код
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));
}
}

Для более сложных сценариев отладки можно создать специализированный логгер с фильтрацией и поиском по данным:

JS
Скопировать код
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');

Интеграция с инструментами профилирования позволяет оценить влияние форматирования на производительность:

JS
Скопировать код
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-объектов:

JS
Скопировать код
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 напрямую влияет на скорость разработки и качество конечного продукта — инвестиции в эти навыки всегда окупаются сторицей.

Загрузка...