Работа с JSON форматом в JavaScript

Раздел: JavaScript -> Основы 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"}

JSON в JavaScript - comments

En
Js json (javascript)