URL: http://github.com/javascript-tutorial/uk.javascript.info/pull/515.patch
аються в подвійні лапки. Це обов’язково. Отже, `age:30` стає `"age":30`. +- Рядки використовують подвійні лапки. Ніяких одинарних або зворотніх лапок у JSON. Тобто `'Іван'` стає `"Іван"`. +- Назви властивостей об’єкта також обертаються в подвійні лапки. Це обов’язково. Тобто `age:30` стає `"age":30`. `JSON.stringify` можна застосувати до примітивів. @@ -83,7 +82,7 @@ JSON підтримує наступні типи даних: - Примітиви: - рядки, - числа, - - бульові значення `true/false`, + - логічні значення `true/false`, - `null`. Наприклад: @@ -100,18 +99,18 @@ alert( JSON.stringify(true) ); // true alert( JSON.stringify([1, 2, 3]) ); // [1,2,3] ``` -JSON -- це лише незалежна специфікація даних, тому деякі притаманні для JavaScript властивості об’єктів пропускаються в `JSON.stringify`. +JSON -- незалежна від мови специфікація даних, тому `JSON.stringify` пропускає деякі специфічні для JavaScript властивості об’єктів. А саме: - Функціональні властивості (методи). - Символьні ключі та значення. -- Властивості, що зберігають `undefined`. +- Властивості, що мають `undefined`. ```js run let user = { sayHi() { // ігнорується - alert("Hello"); + alert("Привіт"); }, [Symbol("id")]: 123, // ігнорується something: undefined // ігнорується @@ -138,7 +137,7 @@ let meetup = { }; alert( JSON.stringify(meetup) ); -/* Вся структура серіалізується: +/* Вся структура перетворена в рядок: { "title":"Конференція", "room":{"number":23,"participants":["Іван","Анна"]}, @@ -173,7 +172,7 @@ JSON.stringify(meetup); // Помилка: Конвертування циклі  -## За винятком та трансформацією: Замінник +## За винятком та трансформацією: replacer Повний синтаксис `JSON.stringify`: @@ -190,7 +189,7 @@ replacer space : Кількість пробілів для форматування -Зазвичай, `JSON.stringify` використовується лише з першим аргументом. Але якщо нам потрібно добре налаштувати процес заміни, наприклад, якщо ми хочемо відфільтрувати циклічні посилання, то ми можемо використовувати другий аргумент `JSON.stringify`. +Зазвичай, `JSON.stringify` використовується лише з першим аргументом. Але якщо нам потрібно налаштувати процес заміни, наприклад, відфільтрувати циклічні посилання, то ми можемо використовувати другий аргумент `JSON.stringify`. Якщо ми передаємо йому масив властивостей, то будуть закодовані лише ці властивості. @@ -213,9 +212,9 @@ alert( JSON.stringify(meetup, *!*['title', 'participants']*/!*) ); // {"title":"Конференція","participants":[{},{}]} ``` -Тут ми, мабуть, занадто суворі. Список властивостей застосовується до всієї структури об’єкта. Отже, об’єкти в `participants` будуть порожніми, тому що `name` не в списку. +Тут ми, мабуть, занадто суворі. Список властивостей застосовується до всієї структури об’єкта. Тому об’єкти в `participants` будуть порожніми, бо `name` немає в списку. -Включімо в список кожної власності, крім `room.occupiedBy`, що призведе до циклічного посилання: +Включімо в список всі властивості, окрім `room.occupiedBy`, яка призводить до циклічного посилання: ```js run let room = { @@ -242,9 +241,9 @@ alert( JSON.stringify(meetup, *!*['title', 'participants', 'place', 'name', 'num Тепер все, крім `occupiedBy`, серіалізується. Але список властивостей досить довгий. -На щастя, ми можемо використовувати функцію замість масиву, в якості `replacer`. +На щастя, в якості `replacer` ми можемо використовувати функцію замість масиву. -Функція буде викликана для кожного `(key, value)`, і повинна повернути значення "replaced", яке буде використовуватися замість оригінального. Або `undefined`, якщо значення буде пропущено. +Функція буде викликана для кожного `(key, value)`, і повинна повернути замінене значення, яке буде використовуватися замість оригінального. Або `undefined`, якщо значення буде пропущено. У нашому випадку ми можемо повернути `value` "як є" для всього, крім `occupiedBy`. Щоб ігнорувати `occupiedBy`, код нижче повертає `undefined`: @@ -276,18 +275,18 @@ name: Іван name: Аліна place: [object Object] number: 23 -occupiedBy: [object Object] +occupiedBy: [object Object] */ ``` -Будь ласка, зверніть увагу, що функція `replacer` отримує кожну пару ключ/значення, включаючи вкладені об’єкти та елементи масиву. Він застосовується рекурсивно. Значення `this` всередині `replacer` -- це об’єкт, який містить поточну властивість. +Будь ласка, зверніть увагу, що функція `replacer` отримує кожну пару ключ/значення, включаючи вкладені об’єкти та елементи масиву. І вона застосовується рекурсивно. Значення `this` всередині `replacer` -- це об’єкт, який містить поточну властивість. -Перший виклик особливий. Він зроблений з використанням спеціального "об’єкта обгортки": `{"": meetup}`. Іншими словами, перша пара `(key, value)` має порожній ключ, а значення є цільовим об’єктом загалом. Ось чому перший рядок -- `":[object Object]"` в прикладі вище. +Перший виклик особливий. Він зроблений з використанням спеціального "об’єкта обгортки": `{"": meetup}`. Іншими словами, перша пара `(key, value)` має порожній ключ, а значення є цільовим об’єктом загалом. Ось чому перший рядок в прикладі вище буде `":[object Object]"` . -Ідея полягає в тому, щоб забезпечити якомога більше потужності для функції `replacer`: вона має можливість аналізувати та замінити/пропустити навіть весь об’єкт, якщо це необхідно. +Ідея полягає в тому, щоб забезпечити якомога більше можливостей для функції `replacer` -- вона має можливість аналізувати та замінити/пропустити навіть весь об’єкт, якщо це необхідно. -## Форматування: пробіл +## Форматування: space Третій аргумент `JSON.stringify(value, replacer, space)` -- це кількість пробілів, що використовуються для гарного форматування. @@ -329,13 +328,13 @@ alert(JSON.stringify(user, null, 2)); */ ``` -Третій аргумент також може бути рядок. У цьому випадку рядок використовується для відступу замість числа пробілів. +Третій аргумент також може бути рядок. У цьому випадку рядок використовується для відступу замість ряда пробілів. Параметр `space` використовується виключно для логування та гарного виводу. ## Спеціальний "toJSON" -Подібно до методу `toString` (для перетворення об’єкта в рядок), об’єкт також має метод `toJSON` для його перетворення в JSON. Функція `JSON.stringify` автоматично викликає цей метод. +Подібно до методу `toString` для перетворення в рядок, об’єкт також може мати метод `toJSON` для перетворення в JSON. Функція `JSON.stringify` автоматично викликає цей метод, якщо він є. Наприклад: @@ -362,9 +361,9 @@ alert( JSON.stringify(meetup) ); */ ``` -Тут ми бачимо, що `date` `(1)` став рядком. Це тому, що всі дати мають вбудований метод `toJSON`, який повертає такий рядок в такому вигляді. +Тут ми бачимо, що `date` `(1)` став рядком. Це тому, що всі об’єкти типу `Date` мають вбудований метод `toJSON`, який повертає такий рядок. -Тепер додаймо спеціальний `toJSON` для нашого об’єкта `room` `(2)`: +Тепер додамо власну реалізацію методу `toJSON` в нашо об’єкт `room` `(2)`: ```js run let room = { @@ -396,7 +395,7 @@ alert( JSON.stringify(meetup) ); */ ``` -Як бачимо, `toJSON` використовується як для прямого виклику `JSON.stringify(room)`, а також коли властивість `room` вкладена в іншому закодованому об’єкті. +Як ми можемо побачити, `toJSON` використовується як при прямому виклику `JSON.stringify(room)`, так і коли `room` вкладений в іншому серіалізованому об’єкті. ## JSON.parse @@ -453,20 +452,20 @@ let json = `{ Існує інший формат, який називається [JSON5](http://json5.org/), що підтримує ключі не обернені в лапки, коментарі тощо. Але це окрема бібліотека, а не частина специфікації мови. -Звичайний JSON є настільки строгим не тому, що її розробники ледачі, а тому, що дозволяє легко, надійно та дуже швидко реалізувати алгоритм кодування та читання. +Звичайний JSON є настільки строгим не тому, що його розробники ледачі, а тому, що дозволяє легко, надійно та дуже швидко реалізувати алгоритм кодування та читання. -## Використання функції відновлення +## Використання reviver Уявіть, що ми отримали серіалізований об’єкт `meetup` з сервера. -Це виглядає так: +Ось такий: ```js // title: (meetup title), date: (meetup date) let str = '{"title":"Конференція","date":"2017-11-30T12:00:00.000Z"}'; ``` -...І тепер нам потрібно *десеріалізувати* цей об’єкт, щоб перетворити його в об’єкт JavaScript. +...І тепер нам потрібно *десеріалізувати* цей об’єкт, тобто знову перетворити його в об’єкт JavaScript. Зробімо це, викликавши `JSON.parse`: @@ -482,7 +481,7 @@ alert( meetup.date.getDate() ); // Помилка! Ой! Помилка! -Значення `meetup.date` -- це рядок, а не об’єкт `Date`. Як `JSON.parse` знає, що він повинен перетворити цей рядок на об’єкт `Date`? +Значення `meetup.date` -- це рядок, а не об’єкт `Date`. Як `JSON.parse` міг знати, що він повинен перетворити цей рядок на об’єкт `Date`? Передаймо до `JSON.parse` функції відновлення як другий аргумент, який повертає всі значення "як є", але `date` стане об’єктом `Date`: diff --git a/1-js/05-data-types/12-json/json-meetup.svg b/1-js/05-data-types/12-json/json-meetup.svg index 3fa32a261..8aa15bd1f 100644 --- a/1-js/05-data-types/12-json/json-meetup.svg +++ b/1-js/05-data-types/12-json/json-meetup.svg @@ -1 +1 @@ -