JSON.stringify: примеры (JAVASCRIPT)
JSON.stringify(value: Any, [replacer, space]): StringОсновы функции JSON.stringify
JSON.stringify()
— это метод в JavaScript, который преобразует значение JavaScript в строку JSON. Он часто используется для отправки данных на сервер, сохранения состояния приложения в локальном хранилище или логирования сложных объектов в читаемом формате.Синтаксис функции: JSON.stringify(value[, replacer[, space]]).
Первый аргумент (value) — обязательный. Это значение, которое нужно преобразовать в строку JSON. Может быть объектом, массивом, числом, строкой, логическим значением или null.
Второй аргумент (replacer) — необязательный. Он определяет, какие свойства объекта включать в строку JSON, или может быть функцией, преобразующей значения перед их сериализацией. Также может быть массивом строк, который указывает ключи для включения.
Третий аргумент (space) — необязательный. Используется для добавления отступов, пробелов или строк для форматирования вывода, что делает JSON более читаемым для человека. Может быть числом (указывает количество пробелов) или строкой (используется как отступ).
Метод возвращает строку, представляющую значение в формате JSON. Для значений, которые не могут быть представлены в JSON (например, undefined, функции, символы), поведение различается: свойства с такими значениями в объектах опускаются, а сами значения в массивах заменяются на null. Для циклических ссылок выбрасывается ошибка TypeError.
Базовые примеры использования
Сериализация простого объекта:
const obj = { name: "Анна", age: 30, city: "Москва" };
console.log(JSON.stringify(obj));{"name":"Анна","age":30,"city":"Москва"}Использование replacer в виде массива для выбора свойств:
const obj = { id: 1, title: "Статья", author: "Иван", year: 2023 };
console.log(JSON.stringify(obj, ['id', 'title']));{"id":1,"title":"Статья"}Использование replacer в виде функции для преобразования значений:
const obj = { a: 10, b: "текст", c: true };
const result = JSON.stringify(obj, (key, value) => {
if (typeof value === 'number') return value * 2;
return value;
});
console.log(result);{"a":20,"b":"текст","c":true}Форматирование вывода с помощью параметра space:
const obj = { data: { users: [{name: "Алексей"}, {name: "Мария"}] } };
console.log(JSON.stringify(obj, null, 2));{
"data": {
"users": [
{
"name": "Алексей"
},
{
"name": "Мария"
}
]
}
}Поведение с неподдерживаемыми значениями:
const obj = { func: function() {}, undef: undefined, num: 42 };
console.log(JSON.stringify(obj));
const arr = [undefined, function() {}, 42];
console.log(JSON.stringify(arr));{"num":42}
[null,null,42]Похожие функции в JavaScript
JSON.parse() — обратная операция для stringify. Преобразует строку JSON обратно в объект JavaScript. Используется при получении данных с сервера или чтении из локального хранилища.
console.dir() и console.table() — методы консоли для вывода структурированной информации об объекте в удобном для чтения виде прямо в консоли браузера. Не производят сериализацию в строку, а предназначены для отладки.
Методы глубокого клонирования (например, использование structuredClone() или комбинации JSON.parse(JSON.stringify(obj))). Эти подходы позволяют создать глубокую копию объекта, но второй вариант работает только с JSON-совместимыми данными и преобразует даты в строки, игнорирует функции.
Выбор метода зависит от задачи: для передачи данных используют JSON.stringify, для отладки в консоли — console.dir, для глубокого копирования — structuredClone или комбинацию методов JSON.
Типичные ошибки
Циклические ссылки: Попытка сериализации объекта, содержащего ссылки на самого себя или взаимные ссылки между объектами, приводит к ошибке.
const obj = { name: "Объект" };
obj.self = obj; // Создание циклической ссылки
try {
JSON.stringify(obj);
} catch (e) {
console.error(e.message);
}TypeError: Converting circular structure to JSON
Потеря данных при сериализации неподдерживаемых типов: Свойства со значениями undefined, функции, символы игнорируются при сериализации объекта, что может привести к неожиданной потере данных.
const obj = { importantData: undefined, id: 1 };
console.log(JSON.stringify(obj));{"id":1}Некорректное использование reviver/replacer: Ошибки в логике функции-replacer могут привести к неполным или искаженным данным.
const obj = { a: 1, b: 2, c: 3 };
// replacer случайно удаляет все свойства
const result = JSON.stringify(obj, (key, value) => {
if (key === 'b') return undefined; // Удаляет только 'b'
return value;
});
console.log(result);{"a":1,"c":3}Сериализация больших объектов или неявное преобразование: Может привести к проблемам с производительностью или неожиданному результату, если объект имеет метод toJSON, который возвращает некорректные данные.
Изменения в последних версиях
Функция JSON.stringify остается стабильной и хорошо обратно совместимой. Существенных изменений в её базовом поведении в последних версиях ECMAScript не было.
Однако, с развитием стандарта JavaScript, изменилась экосистема типов данных, с которыми работает функция. Например, лучше определено поведение с объектами Map, Set, TypedArray и BigInt — они сериализуются в пустые объекты {}, если не определен их метод toJSON, так как они не являются JSON-сериализуемыми по умолчанию.
В спецификации ES2019 было уточнено, что строка, возвращаемая JSON.stringify, должна состоять из символов Unicode, соответствующих графемным кластерам. Это техническое уточнение, которое редко затрагивает повседневное использование.
Основные улучшения касаются не самой функции, а окружения: инструменты отладки в браузерах и средах выполнения лучше отображают структурированные данные, а альтернативные методы сериализации (например, для бинарных данных) развиваются в отдельных API.
Расширенные и нестандартные примеры
Использование метода toJSON для кастомной сериализации объекта:
const book = {
title: "JavaScript",
releaseDate: new Date('2023-01-01'),
toJSON() {
return {
title: this.title,
year: this.releaseDate.getFullYear()
};
}
};
console.log(JSON.stringify(book));{"title":"JavaScript","year":2023}Сериализация с использованием replacer для "скрытия" конфиденциальных данных:
const user = { login: "admin", password: "secret123", role: "manager" };
const safeStringify = (obj) => {
return JSON.stringify(obj, (key, value) => {
return (key === 'password') ? '***' : value;
});
};
console.log(safeStringify(user));{"login":"admin","password":"***","role":"manager"}Создание форматированного JSON с использованием строки в качестве отступа:
const data = { level1: { level2: { level3: "данные" } } };
console.log(JSON.stringify(data, null, '--'));{
--"level1": {
----"level2": {
------"level3": "данные"
----}
--}
}Рекурсивный replacer для обработки вложенных структур со специальной логикой, например, преобразование всех строк в верхний регистр:
const obj = { name: "тест", nested: { value: "пример" }, tags: ["js", "json"] };
const result = JSON.stringify(obj, (key, val) => {
if (typeof val === 'string') return val.toUpperCase();
return val;
}, 2);
console.log(result);{
"name": "ТЕСТ",
"nested": {
"value": "ПРИМЕР"
},
"tags": [
"JS",
"JSON"
]
}Пример сериализации объекта, содержащего экземпляры классов, где нужно сохранить только определенные свойства:
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
get profile() {
return `${this.name} <${this.email}>`;
}
}
const user = new User("Олег", "oleg@example.com");
// Сериализуем только собственные, перечисляемые свойства экземпляра
const replacer = (key, value) => {
// Игнорируем геттеры (например, 'profile')
if (typeof value === 'function') return undefined;
return value;
};
console.log(JSON.stringify(user, replacer));{"name":"Олег","email":"oleg@example.com"}Альтернативы в других языках программирования
PHP: Функция json_encode(). Аналогично преобразует значение в строку JSON. Отличие в обработке кодировок и дополнительных флагах, например, JSON_PRETTY_PRINT для форматирования.
$array = array("name" => "Иван", "age" => 25);
echo json_encode($array);{"name":"\u0418\u0432\u0430\u043d","age":25}Python: Модуль json с функцией json.dumps(). Имеет схожий синтаксис, параметры indent для отступов и ensure_ascii для управления кодированием символов.
import json
data = {"name": "Иван", "age": 25}
print(json.dumps(data, ensure_ascii=False, indent=2)){
"name": "Иван",
"age": 25
}MySQL: Функция JSON_OBJECT() и подобные. Позволяют формировать JSON прямо в SQL-запросе, что полезно для агрегации данных.
SELECT JSON_OBJECT('id', id, 'name', name) FROM users;C#: Метод JsonSerializer.Serialize() из пространства имен System.Text.Json. Требует больше настроек для работы с типами и циклическими ссылками, но обеспечивает высокую производительность.
var person = new { Name = "Иван", Age = 25 };
string json = JsonSerializer.Serialize(person);{"Name":"Иван","Age":25}Главные отличия от JavaScript часто заключаются в обработке кодировки символов, наличии дополнительных флагов сериализации и интеграции со статической типизацией.