JSON.parse()
Статичний метод JSON.parse()
(розібрати) розбирає рядок у форматі JSON, конструюючи значення чи об'єкт JavaScript, описаний рядком. Можна передати функцію як необов'язковий параметр reviver для виконання трансформацій над результівним об'єктом перед його поверненням.
Спробуйте його в дії
Синтаксис
JSON.parse(text)
JSON.parse(text, reviver)
Параметри
text
(текст)Рядок, який буде розібрано як JSON. Опис синтаксису JSON можна знайти в розділі про об'єкт
JSON
.reviver
(відроджувач) Необов'язковеЯкщо є функцією — цей параметр прописує те, як початкове, сконструйоване під час розбору, значення слід трансформувати перед його поверненням. Невикличні значення ігноруються. Функція викликається з наступними аргументами:
key
Ключ, який відповідає значенню.
value
Значення – результат розбору.
Повернене значення
Об'єкт
, Масив
, рядок, число, булеве значення або null
, згідно з переданим в text
рядком JSON.
Винятки
SyntaxError
Викидається, якщо рядок до розбору не є дійсним JSON.
Опис
JSON.parse()
розбирає рядок JSON згідно з граматикою JSON, а потім обчислює рядок так, ніби він був виразом JavaScript. Єдиний випадок, за якого дрібка тексту JSON представляє значення, котре відрізняється від такого самого виразу JavaScript – обробка ключа "__proto__"
: дивіться Синтаксис літерала об'єкта і JSON.
Параметр reviver
Якщо заданий reviver
(відновник), то значення, обчислене при розборі, перетворюється перед поверненням. А саме, обчислене значення і всі його властивості (проходом в глибину), починаючи від властивостей найбільшої вкладеності, й аж до самого кореневого значення – пропускаються крізь reviver
.
reviver
при виклику отримує об'єкт, котрий містить властивість, що обробляється, як значення this
, а також два аргументи: key
та value
, котрі представляють ім'я в рядковому вигляді (навіть коли об'єкт є масивом) і значення властивості. Якщо функція reviver
повертає undefined
(чи не повертає жодного значення – наприклад, коли виконання звалюється з кінця функції), то властивість видаляється з об'єкта. Інакше – властивість перевизначається з поверненим значенням. Якщо reviver
перетворює лише частину значень, то слід пересвідчитися, що всі неперетворені значення повертаються як було: інакше вони будуть видалені з результівного об'єкта.
Подібно до параметра JSON.stringify()
replacer
, reviver
в останню чергу викликається на кореневому об'єкті з порожнім рядком як key
й кореневим об'єктом як value
. Для тексту JSON, що впізнається за примітивне значення, reviver
буде викликаний один раз.
Зверніть увагу, що reviver
спрацьовує після розбору значення. Тому, наприклад, числа в тексті JSON вже будуть перетворені на числа JavaScript, в процесі чого можуть втратити частину точності. Для передачі великих чисел без втрати точності їх слід серіалізувати як рядки – і відновлювати їх до BigInt чи якогось іншого відповідного довільно точного формату.
Приклади
Застосування JSON.parse()
JSON.parse("{}"); // {}
JSON.parse("true"); // true
JSON.parse('"foo"'); // "foo"
JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
JSON.parse("null"); // null
Застосування параметра reviver
JSON.parse(
'{"p": 5}',
(key, value) =>
typeof value === "number"
? value * 2 // повертає значення * 2 для чисел
: value // повертає все інше незмінним
);
// { p: 10 }
JSON.parse('{"1": 1, "2": 2, "3": {"4": 4, "5": {"6": 6}}}', (key, value) => {
console.log(key);
return value;
});
// 1
// 2
// 4
// 6
// 5
// 3
// ""
Використання reviver у парі з replacer у JSON.stringify()
Для коректної роботи зі значенням (щоб воно десеріалізувалось до такого самого вихідного об'єкта), процес серіалізації мусить зберігати інформацію про типи. Наприклад, можна застосувати для цього параметр JSON.stringify()
replacer
:
// Map в загальному випадку серіалізуються як об'єкти без властивостей.
// Можна застосувати замінювач, аби вказати, які записи повинні бути серіалізовані.
const map = new Map([
[1, "один"],
[2, "два"],
[3, "три"],
]);
const jsonText = JSON.stringify(map, (key, value) =>
value instanceof Map ? Array.from(value.entries()) : value
);
console.log(jsonText);
// [[1,"один"],[2,"два"],[3,"три"]]
const map2 = JSON.parse(jsonText, (key, value) =>
key === "" ? new Map(value) : value
);
console.log(map2);
// Map { 1 => "один", 2 => "два", 3 => "три" }
Через те, що JSON не має синтаксичного простору для метаданих з анотаціями типу, для відновлення значень, що не є звичайними об'єктами, слід розглянути наступні варіанти:
- Серіалізувати увесь об'єкт у рядок і додати префікс у вигляді тегу типу.
- "Вгадувати" на основі структури даних (наприклад, масив з масивів двох значень)
- Якщо форма даних – фіксована, то на основі імені властивості (наприклад, всі властивості, що звуться
registry
, містять об'єктиMap
).
JSON.parse() не допускає висячих ком
// обидва викинуть SyntaxError
JSON.parse("[1, 2, 3, 4, ]");
JSON.parse('{"foo" : 1, }');
JSON.parse() не допускає одинарних лапок
// викине SyntaxError
JSON.parse("{'foo': 1}");
Специфікації
Сумісність із браузерами
desktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
parse
|
Chrome Full support 3 | Edge Full support 12 | Firefox Full support 3.5 | Internet Explorer Full support 8 | Opera Full support 10.5 | Safari Full support 4 | WebView Android Full support 37 | Chrome Android Full support 18 | Firefox for Android Full support 4 | Opera Android Full support 11 | Safari on iOS Full support 4 | Samsung Internet Full support 1.0 | Deno Full support 1.0 | Node.js Full support 0.10.0 |