diff --git a/files/uk/web/javascript/reference/global_objects/json/parse/index.md b/files/uk/web/javascript/reference/global_objects/json/parse/index.md index 96c0cc5df3..0c282f120b 100644 --- a/files/uk/web/javascript/reference/global_objects/json/parse/index.md +++ b/files/uk/web/javascript/reference/global_objects/json/parse/index.md @@ -28,6 +28,10 @@ JSON.parse(text, reviver) - : Ключ, який відповідає значенню. - `value` - : Значення – результат розбору. + - `context` {{optional_inline}} + - : Об'єкт контексту, що зберігає стан, який стосується відродження поточного виразу. Цей об'єкт створюється заново для кожного заклику функції-відроджувача. Він передається лише при відродженні примітивних значень, але не тоді, коли `value` є об'єктом або масивом. У цього об'єкта є наступна властивість: + - `source` + - : Вихідний рядок JSON, що представляє це значення. ### Повернене значення @@ -46,7 +50,7 @@ JSON.parse(text, reviver) Якщо заданий `reviver` (відновник), то значення, обчислене при розборі, _перетворюється_ перед поверненням. А саме, обчислене значення і всі його властивості (проходом [в глибину](https://uk.wikipedia.org/wiki/%D0%9F%D0%BE%D1%88%D1%83%D0%BA_%D1%83_%D0%B3%D0%BB%D0%B8%D0%B1%D0%B8%D0%BD%D1%83)), починаючи від властивостей найбільшої вкладеності, й аж до самого кореневого значення – пропускаються крізь `reviver`. -Параметр `reviver` при виклику отримує об'єкт, котрий містить властивість, що обробляється, як значення `this` (якщо не визначити `reviver` як стрілкову функцію – тоді окремого зв'язування `this` не буде), а також два аргументи: `key` та `value`, котрі представляють ім'я в рядковому вигляді (навіть коли об'єкт є масивом) і значення властивості. Якщо функція `reviver` повертає {{jsxref("undefined")}} (чи не повертає жодного значення – наприклад, коли виконання звалюється з кінця функції), то властивість видаляється з об'єкта. Інакше – властивість перевизначається з поверненим значенням. Якщо `reviver` перетворює лише частину значень, то слід пересвідчитися, що всі неперетворені значення повертаються як було: інакше вони будуть видалені з результівного об'єкта. +Параметр `reviver` при виклику отримує об'єкт, котрий містить властивість, що обробляється, як значення `this` (якщо не визначити `reviver` як стрілкову функцію – тоді окремого зв'язування `this` не буде), а також два аргументи: `key` та `value`, котрі представляють ім'я в рядковому вигляді (навіть коли об'єкт є масивом) і значення властивості. У випадку примітивних значень передається додатковий параметр `context`, який містить вихідний текст значення. Якщо функція `reviver` повертає {{jsxref("undefined")}} (чи не повертає жодного значення – наприклад, коли виконання звалюється з кінця функції), то властивість видаляється з об'єкта. Інакше – властивість перевизначається з поверненим значенням. Якщо `reviver` перетворює лише частину значень, то слід пересвідчитися, що всі неперетворені значення повертаються як було: інакше вони будуть видалені з результівного об'єкта. Подібно до параметра {{jsxref("JSON.stringify()")}} `replacer`, щодо масивів і об'єктів, `reviver` в останню чергу викликається на кореневому об'єкті з порожнім рядком як `key` й кореневим об'єктом як `value`. Для решти дійсних значень JSON `reviver` працює схоже та викликається один раз із порожнім рядком за `key` та самим значенням за `value`. @@ -62,7 +66,20 @@ console.log(transformedObj1); // undefined Немає узагальненого способу це обійти. Не можна окремо обробляти випадок, коли `key` є порожнім рядком, тому що об'єкти JSON також можуть містити ключі, що є порожніми рядками. При реалізації відновника потрібно дуже точно знати, яке перетворення потрібно для кожного ключа. -Зверніть увагу, що `reviver` спрацьовує після розбору значення. Тому, наприклад, числа в тексті JSON вже будуть перетворені на числа JavaScript, в процесі чого можуть втратити частину точності. Для передачі великих чисел без втрати точності їх слід серіалізувати як рядки – і відновлювати їх до [BigInt](/uk/docs/Web/JavaScript/Reference/Global_Objects/BigInt) чи якогось іншого відповідного довільно точного формату. +Зверніть увагу, що `reviver` спрацьовує після розбору значення. Тому, наприклад, числа в тексті JSON вже будуть перетворені на числа JavaScript, в процесі чого можуть втратити частину точності. Одним зі способів передачі великих чисел без втрати точності є серіалізація їх як рядків, а потім відродження до [BigInt](/uk/docs/Web/JavaScript/Reference/Global_Objects/BigInt) або іншого відповідного формату довільної точності. + +Також можна скористатися властивістю `context.source`, щоб звернутися до вихідного тексту JSON, який представляє значення, як показано нижче: + +```js +const bigJSON = '{"gross_gdp": 12345678901234567890}'; +const bigObj = JSON.parse(bigJSON, (key, value, context) => { + if (key === "gross_gdp") { + // Ігнорувати значення, оскільки воно вже втратило точність + return BigInt(context.source); + } + return value; +}); +``` ## Приклади @@ -157,4 +174,5 @@ JSON.parse("{'foo': 1}"); ## Дивіться також +- [Поліфіл сучасної поведінки `JSON.parse` (параметр `context` відроджувача) у складі `core-js`](https://github.com/zloirock/core-js#jsonparse-source-text-access) - {{jsxref("JSON.stringify()")}}