Работа с JSON форматом в JavaScript
Основы JSON в JavaScript
Наиболее эффективный способ работы с JSON в JavaScript - использование встроенных методов JSON.parse() и JSON.stringify(). JSON.parse() преобразует строку JSON в объект JavaScript, а JSON.stringify() преобразует объект JavaScript в строку JSON.
// Пример преобразования строки JSON в объект
const jsonString = '{"name":"Иван","age":30}';
const user = JSON.parse(jsonString);
console.log(user.name); // ИванJs json (json в javascript)
// Пример преобразования объекта в JSON строку
const userObj = { name: "Мария", age: 25 };
const json = JSON.stringify(userObj);
console.log(json); // {"name":"Мария","age":25}Js данные (данные в javascript)
Проблема: При сериализации объектов с циклическими ссылками возникает ошибка TypeError: Converting circular structure to JSON. Также теряются значения undefined, NaN и Infinity (преобразуются в null).
Решение: Для циклических ссылок можно использовать второй аргумент JSON.stringify() - replacer (функцию или массив ключей), чтобы исключить проблемные поля. Для восстановления специальных значений применяется второй аргумент JSON.parse() - reviver.
Как обработать ошибки при парсинге JSON?
При получении данных из внешних источников строка может быть некорректной. Используется блок try...catch.
try {
const data = JSON.parse('неправильная строка');
} catch (error) {
console.error('Ошибка парсинга JSON:', error.message);
}
Js значение (значения в javascript)
Типичная ошибка - неэкранированные кавычки или лишние запятые. Рекомендуется валидировать JSON перед парсингом.
Как отформатировать JSON с отступами для читаемости?
Третий аргумент JSON.stringify() задает количество пробелов или строку отступа.
const obj = { name: "Алексей", skills: ["JS", "Python"] };
console.log(JSON.stringify(obj, null, 2));Javascript let (оператор let в javascript)
{
"name": "Алексей",
"skills": [
"JS",
"Python"
]
}Js code (код на javascript)
Как выполнить глубокое копирование объекта с помощью JSON?
Метод JSON.parse(JSON.stringify(obj)) создает глубокую копию, но не работает с функциями, датами (преобразуются в строки) и специальными значениями.
const original = { a: 1, b: { c: 2 } };
const copy = JSON.parse(JSON.stringify(original));
copy.b.c = 3;
console.log(original.b.c); // 2 (не изменился)
Проблема: Дата преобразуется в строку, undefined и функции теряются. Для полноценного копирования лучше использовать библиотеки (например, lodash.cloneDeep) или рекурсивную функцию.
Как сериализовать объекты с методами и датами?
Стандартный JSON не поддерживает функции и даты. Можно заменить дату на строку ISO в методе toJSON() объекта, а при парсинге восстановить через reviver.
const user = {
name: "Ольга",
birth: new Date(1995, 5, 15),
sayHi() { console.log("Привет"); },
toJSON() {
return { name: this.name, birth: this.birth.toISOString() };
}
};
const json = JSON.stringify(user);
console.log(json); // {"name":"Ольга","birth":"1995-06-15T00:00:00.000Z"}
// Восстановление даты
const parsed = JSON.parse(json, (key, value) => {
if (key === 'birth') return new Date(value);
return value;
});
console.log(parsed.birth instanceof Date); // true
Расширенные примеры работы с JSON
Ниже приведены нестандартные сценарии использования JSON в JavaScript.
1. Использование BigInt в JSON
JSON не поддерживает тип BigInt. При попытке сериализации возникает ошибка. Можно преобразовать BigInt в строку с особым префиксом и восстановить его при парсинге.
const bigObj = { value: 12345678901234567890n };
// JSON.stringify(bigObj); // TypeError: Do not know how to serialize a BigInt
// Кастомная сериализация
const jsonString = JSON.stringify(bigObj, (key, value) =>
typeof value === 'bigint' ? value.toString() + 'n' : value
);
console.log(jsonString); // {"value":"12345678901234567890n"}
// Восстановление
const restored = JSON.parse(jsonString, (key, value) => {
if (typeof value === 'string' && /^\d+n$/.test(value)) {
return BigInt(value.slice(0, -1));
}
return value;
});
console.log(restored.value); // 12345678901234567890n
{"value":"12345678901234567890n"}
12345678901234567890n
2. Работа с циклическими ссылками через replacer
Использование массива ключей или функции для исключения циклических полей.
const objA = { name: "A" };
const objB = { name: "B", ref: objA };
objA.ref = objB; // цикл
// Используем replacer-функцию с кэшем
const seen = new WeakSet();
const result = JSON.stringify(objA, (key, value) => {
if (typeof value === 'object' && value !== null) {
if (seen.has(value)) return '[Circular]';
seen.add(value);
}
return value;
});
console.log(result);
// {"name":"A","ref":{"name":"B","ref":"[Circular]"}}
{"name":"A","ref":{"name":"B","ref":"[Circular]"}}
3. Восстановление Map и Set из JSON
Стандартный JSON не знает о Map и Set. Можно сериализовать их как массивы пар или элементов, а при парсинге восстанавливать.
const map = new Map([['key1', 'value1'], ['key2', 'value2']]);
const set = new Set([1, 2, 3]);
const customJSON = JSON.stringify({
map: Array.from(map.entries()),
set: Array.from(set)
});
console.log(customJSON);
// {"map":[["key1","value1"],["key2","value2"]],"set":[1,2,3]}
const parsed = JSON.parse(customJSON, (key, value) => {
if (key === 'map') return new Map(value);
if (key === 'set') return new Set(value);
return value;
});
console.log(parsed.map.get('key1')); // 'value1'
console.log(parsed.set.has(2)); // true
{"map":[["key1","value1"],["key2","value2"]],"set":[1,2,3]}
value1
true
4. Фильтрация полей при сериализации
Третий параметр JSON.stringify() - массив ключей, которые нужно включить в вывод.
const user = {
id: 1,
name: "Дмитрий",
password: "secret",
email: "dmitry@example.com"
};
const safeUser = JSON.stringify(user, ['id', 'name', 'email']);
console.log(safeUser);
// {"id":1,"name":"Дмитрий","email":"dmitry@example.com"}
{"id":1,"name":"Дмитрий","email":"dmitry@example.com"}