Aytaylik, bizda murakkab obyekt bor va biz uni matnga aylantirishni, uni tarmoq orqali yuborishni yoki shunchaki logga yozish uchun chiqarishni xohlaymiz.
Tabiiyki, bunday matn barcha muhim xususiyatlarni oâz ichiga olishi kerak.
Biz konvertatsiyani quyidagi tarzda amalga oshirishimiz mumkin:
let user = {
name: "John",
age: 30,
toString() {
return `{name: "${this.name}", age: ${this.age}}`;
}
};
alert(user); // {name: "John", age: 30}
â¦Ammo rivojlanish jarayonida yangi xususiyatlar qoâshiladi, eski xususiyatlar qayta nomlanadi va oâchiriladi. Bunday toString-ni har doim yangilash ogâriqli boâlishi mumkin. Biz undagi xususiyatlarni tsiklashni urinib koârishimiz mumkin edi, lekin agar obyekt murakkab boâlsa va xususiyatlarida ichki obyektlar boâlsachi? Biz ularning konvertatsiyasini ham amalga oshirishimiz kerak. Agar biz obyektni tarmoq orqali joânatayotgan boâlsak, u holda qabul qiluvchida bizning obyektimizni âoâqishiâ uchun kodni yetkazib berishimiz kerak.
Yaxshiyamki, bularning barchasini hal qilish uchun kod yozishning hojati yoâq. Vazifa allaqachon hal qilingan.
JSON.stringify
JSON (JavaScript Object Notation) qiymatlar va moslamalarni aks ettirish uchun umumiy formatdir. U RFC 4627 standartidagi kabi tavsiflanadi. Dastlab u JavaScript uchun yaratilgan, ammo boshqa koâplab tillarda ham uni boshqarish uchun kutubxonalar mavjud. Mijoz JavaScript-ni ishlatganda va server Ruby/PHP/Java/nima boâlganda ham maâlumotlar almashinuvi uchun JSON-dan foydalanish oson.
JavaScript quyidagi usullarni taqdim etadi:
JSON.stringifyobyektlarni JSON-ga aylantirish uchun.JSON.parseJSON-ni obyektga qaytarish uchun.
Misol uchun, bu yerda biz talaba maâlumotlarini JSON.stringify aylantiramiz:
let student = {
name: 'John',
age: 30,
isAdmin: false,
courses: ['html', 'css', 'js'],
wife: null
};
let json = JSON.stringify(student);
alert(typeof json); // bizda matn bor!
alert(json);
/* JSON-kodlangan obyekt:
{
"name": "John",
"age": 30,
"isAdmin": false,
"courses": ["html", "css", "js"],
"wife": null
}
*/
JSON.stringify(student) usuli obyektni oladi va uni matnga aylantiradi.
Natija json satri JSON tomonidan kodlangan yoki ketma-ketlashtirilgan yoki obyekt deb nomlanadi. Biz uni tarmoq orqali yuborishga yoki oddiy maâlumotlar omboriga qoâyishga tayyormiz.
Iltimos, unutmangki, JSON-kodlangan obyekt obyekt adabiyotidan bir necha muhim farqlarga ega:
- Matnlar ikki tirnoqdan foydalanishadi. JSON-da bitta tirnoq yoki teskari tirnoq yoâq. Shunday qilib,
'John'"John"boâladi. - Obyektning mulk nomlari ham ikki tirnoqdan foydalanishadi. Bu majburiy. Shunday qilib
'age': 30"age":30aylanadi.
JSON.stringify ibtidoiylarga ham qoâllanilishi mumkin.
JSON quyidagi maâlumotlar turlarini qoâllab-quvvatlaydi
- Obyektlar
{ ... } - Massivlar
[ ... ] - Primitivlar:
- matnlar,
- raqamlar,
- mantiqiy qiymatlar
true/false, null.
Masalan:
// JSON-dagi raqam shunchaki raqam
alert( JSON.stringify(1) ) // 1
// JSON-dagi matn hali ham matn, ammo ikkita tirnoqli
alert( JSON.stringify('test') ) // "test"
alert( JSON.stringify(true) ); // true
alert( JSON.stringify([1, 2, 3]) ); // [1,2,3]
JSON maâlumotlar uchun til spetsifikatsiyasidan mustaqil, shuning uchun JSON.stringify JavaScript obyektlarining oâziga xos xususiyatlarini yoâqotadi.
Aynan:
- Funktsiya xususiyatlari (usullari).
- Ramziy xususiyatlar.
undefinedsaqlanadigan xususiyatlar.
let user = {
sayHi() { // e'tiborsiz qoldirildi
alert("Hello");
},
[Symbol("id")]: 123, // e'tiborsiz qoldirildi
something: undefined // e'tiborsiz qoldirildi
};
alert( JSON.stringify(user) ); // {} (bo'sh obyekt)
Bu odatda normal. Agar bu biz istagan narsa boâlmasa, tez orada bu jarayonni qanday qilib sozlash mumkinligini koârib chiqamiz.
Eng yaxshi narsa shundaki, ichki oârnatilgan obyektlar avtomatik ravishda qoâllab-quvvatlanadi va oâzgartiriladi.
Masalan:
let meetup = {
title: "Konferensiya",
room: {
number: 23,
participants: ["john", "ann"]
}
};
alert( JSON.stringify(meetup) );
/* Barcha struktura matnlangan:
{
"title":"Konferensiya",
"room":{"number":23,"participants":["john","ann"]},
}
*/
Muhim cheklov: tsiklik maâlumotnomalar boâlmasligi kerak.
Masalan:
let room = {
number: 23
};
let meetup = {
title: "Konferensiya",
participants: ["john", "ann"]
};
meetup.place = room; // meetup room ga havola qiladi
room.occupiedBy = meetup; // room meetup ga havola qiladi
JSON.stringify(meetup); // Xato: tsiklik tuzilmani JSON-ga aylantirish
Here, the conversion fails, because of circular reference: room.occupiedBy references meetup, and meetup.place references room:
Bu yerda konvertatsiya ishlamayapti, chunki tsiklik maâlumotnoma: room.occupiedBy meetup ga havola qiladi, va meetup.place room ga havola qiladi:
Istisno va konvertatsiya: replacer
JSON.stringify ning toâliq sintaksisi:
let json = JSON.stringify(value[, replacer, space])
- value
- Kodlash uchun qiymat.
- replacer
- Kodlash uchun xususiyatlar majmuasi yoki xaritalash funktsiyasi
function(kalit, qiymat). - space
- Formatlash uchun foydalaniladigan boâsh joy miqdori
Koâpincha, JSON.stringify faqat birinchi argument bilan ishlatiladi. Agar almashtirish jarayonini aniq sozlashimiz kerak boâlsa, masalan, tsiklik maâlumotnomalrni filtrlashimiz kerak boâlsa, biz JSON.stringify ning ikkinchi argumentidan foydalanishimiz mumkin.
Agar biz unga bir qator xususiyatlarni topshirsak, faqat shu xususiyatlar kodlanadi.
Masalan:
let room = {
number: 23
};
let meetup = {
title: "Konferensiya",
participants: [{name: "John"}, {name: "Alice"}],
place: room // meetup room ga havola qiladi
};
room.occupiedBy = meetup; // room meetup ga havola qiladi
alert( JSON.stringify(meetup, ['title', 'participants']) );
// {"title":"Konferensiya","participants":[{},{}]}
Bu yerda biz juda qattiqqoâlmiz. Mulklar roâyxati butun obyekt tuzilishiga qoâllaniladi. Shuning uchun ishtirokchilar boâsh, chunki name roâyxatda yoâq.
Tsiklik maâlumotnomani keltirib chiqaradigan room.occupiedBy dan tashqari har qanday xususiyatni oâz ichiga olaylik:
let room = {
number: 23
};
let meetup = {
title: "Konferensiya",
participants: [{name: "John"}, {name: "Alice"}],
place: room // meetup room ga havola qiladi
};
room.occupiedBy = meetup; // room meetup ga havola qiladi
alert( JSON.stringify(meetup, ['title', 'participants', 'place', 'name', 'number']) );
/*
{
"title":"Konferensiya",
"participants":[{"name":"John"},{"name":"Alice"}],
"place":{"number":23}
}
*/
Endi occupiedBy dan tashqari hamma narsa seriyalashtirilgan. Ammo mulk roâyxati juda uzun.
Yaxshiyamki, biz o'rnini bosuvchi sifatida massiv oârniga funktsiyadan foydalanishimiz mumkin.
Funksiya har bir (kalit, qiymat) juftligi uchun chaqiriladi va asl qiymat oârniga âalmashtirilganâ qiymatni qaytarishi kerak.
Bizning holatimizda, emptyBy dan tashqari hamma narsa uchun value ni qaytarishimiz mumkin. occupiedBy ni eâtiborsiz qoldirish uchun quyidagi kod undefined ni qaytaradi:
let room = {
number: 23
};
let meetup = {
title: "Konferensiya",
participants: [{name: "John"}, {name: "Alice"}],
place: room // meetup room ga havola qiladi
};
room.occupiedBy = meetup; // room meetup ga havola qiladi
alert( JSON.stringify(meetup, function replacer(key, value) {
alert(`${key}: ${value}`); // o'rinbosar nima olishini ko'rish uchun
return (key == 'occupiedBy') ? undefined : value;
}));
/* key:value o'rnini bosadigan juftlar:
: [object Object]
title: Konferensiya
participants: [object Object],[object Object]
0: [object Object]
name: John
1: [object Object]
name: Alice
place: [object Object]
number: 23
occupiedBy: [object Object]
*/
Iltimos, shuni yodda tutingki, replacer funktsiyasi har bir kalit/qiymat juftligini, shu jumladan ichki obyektlar va massiv elementlarini oladi. U rekursiv tarzda qoâllaniladi. this ichidagi replacer qiymat â joriy xususiyatni oâz ichiga olgan obyekt.
Birinchi chaqiruv maxsus. U maxsus âoârash obâektiâ yordamida tayyorlanadi: {"": meetup}. Boshqacha qilib aytganda, birinchi (kalit, qiymat) jufti boâsh kalitga ega va qiymat umuman maqsadli obyektdir. Shuning uchun birinchi satr yuqoridagi misolda ":[object Object]" dir.
Ushbu gâoya replacer ga imkon qadar koâproq kuch berishdir: agar kerak boâlsa, butun obyektni tahlil qilish va almashtirish/oâtkazib yuborish imkoniyati mavjud.
Formatlash: spacer
JSON.stringify(value, replacer, spaces) ning uchinchi argumenti chiroyli formatlash uchun ishlatiladigan boâshliqlar soni.
Ilgari, barcha torlangan obyektlar hech qanday chuqurlik va qoâshimcha boâshliqlarga ega emas edi. Obyektni tarmoq orqali yuborishni istasak yaxshi boâladi. spacer argumenti faqat chiroyli chiqish uchun ishlatiladi.
Bu erda spacer = 2 JavaScript-ga bir nechta satrlarda ichki obyektlarni koârsatishni, obyekt ichidagi 2 boâsh joyni koârsatishni aytadi:
let user = {
name: "John",
age: 25,
roles: {
isAdmin: false,
isEditor: true
}
};
alert(JSON.stringify(user, null, 2));
/* ikki bo'shliq indentlari:
{
"name": "John",
"age": 25,
"roles": {
"isAdmin": false,
"isEditor": true
}
}
*/
/* for JSON.stringify(user, null, 4) natija yanada chuqurroq bo'ladi:
{
"name": "John",
"age": 25,
"roles": {
"isAdmin": false,
"isEditor": true
}
}
*/
spaces parametri faqat logga yozish va chiroyli chiqish uchun ishlatiladi.
Maxsus âtoJSONâ
Matn konvertatsiyasi uchun toString singari, obyek konvertatsiyasi uchun toJSON usulini taqdim etishi mumkin. Agar mavjud boâlsa, JSON.stringify uni avtomatik ravishda chaqiradi.
Masalan:
let room = {
number: 23
};
let meetup = {
title: "Konferensiya",
date: new Date(Date.UTC(2017, 0, 1)),
room
};
alert( JSON.stringify(meetup) );
/*
{
"title":"Konferensiya",
"date":"2017-01-01T00:00:00.000Z", // (1)
"room": {"number":23} // (2)
}
*/
Bu erda date(1) matnga aylanganini koârishimiz mumkin. Buning sababi shundaki, barcha sanalarda bunday turdagi matnga qaytaradigan oârnatilgan toJSON usuli mavjud.
Endi room(2) obyekti uchun odatiy toJSON qoâshamiz:
let room = {
number: 23,
toJSON() {
return this.number;
}
};
let meetup = {
title: "Konferensiya",
room
};
alert( JSON.stringify(room) ); // 23
alert( JSON.stringify(meetup) );
/*
{
"title":"Konferensiya",
"room": 23
}
*/
Koârib turganimizdek, toJSON toâgâridan-toâgâri chaqiruv uchun ishlatiladi JSON.stringify(room) va ichki oârnatilgan obyekt uchun.
JSON.parse
JSON-matnni dekodlash uchun bizga JSON.parse nomli boshqa usul kerak.
Sintaksis:
let value = JSON.parse(str, [reviver]);
- str
- JSON-matn ajratish uchun.
- reviver
- Har bir
(kalit,qiymat)juftligi uchun chaqiriladigan va qiymatni oâzgartirishi mumkin boâlgan ixtiyoriy funktsiya(kalit, qiymat).
Masalan:
// torli qator
let numbers = "[0, 1, 2, 3]";
numbers = JSON.parse(numbers);
alert( numbers[1] ); // 1
Yoki ichki obyektlar uchun:
let userData = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }';
let user = JSON.parse(userData);
alert( user.friends[1] ); // 1
JSON kerakli darajada murakkab boâlishi mumkin, obyektlar va massivlar boshqa obyektlar va massivlarni oâz ichiga olishi mumkin. Ammo ular formatga boâysunishlari kerak.
Qoâlda yozilgan JSON-dagi odatdagi xatolar (baâzida uni koddagi nosozliklarni tuzatish maqsadida yozishimiz kerak):
let json = `{
name: "John", // xato: qoshtirnoqsiz xususiyat nomi
"surname": 'Smith', // xato: bitta qoshtirnoq qiymati (ikkita bo'lishi kerak)
'isAdmin': false // xato: kalitda bitta qoshtirnoq (ikkita bo'lishi kerak)
"birthday": new Date(2000, 2, 3), // xato: "new" ga yo'l qo'yilmaydi, faqat bo'sh qiymatlar
"friends": [0,1,2,3] // mana barchasi yaxshi
}`;
Bundan tashqari, JSON izohlarni qoâllab-quvvatlamaydi. JSON-ga izoh qoâshish uni bekor qiladi.
JSON5 nomli yana bir format mavjud , bu qoshtirnoqsiz kalitlarga, izohlarga va hokazolarga imkon beradi, ammo bu tilning oâziga xos xususiyatlarida emas, balki mustaqil kutubxona.
Oddiy JSON â bu ishlab chiquvchilar dangasa boâlgani uchun emas, balki tahlil algoritmini oson, ishonchli va juda tez amalga oshirishga imkon berish uchun qatâiydir.
Reviverdan foydalanish
Tasavvur qiling, biz serverdan meetup obyektini oldik.
Bu shunday koârinadi:
// title: (meetup title), date: (meetup date)
let str = '{"title":"Konferensiya","date":"2017-11-30T12:00:00.000Z"}';
â¦Va endi biz uni JavaScript obyektiga aylantirish uchun deserializatsiya qilishimiz kerak.
Buni JSON.parse ga chaqiruv qilib bajaramiz:
let str = '{"title":"Konferensiya","date":"2017-11-30T12:00:00.000Z"}';
let meetup = JSON.parse(str);
alert( meetup.date.getDate() ); // Xato!
Voy! Xato!
meetup.date ning qiymati Date obyekti emas, balki matndir. Qanday qilib JSON.parse ushbu matnni Date ga oâzgartirishi kerakligini bilishi mumkin?
JSON.parse ga barcha qiymatlarni âborichaâ qaytaradigan qayta tiklash funktsiyasiga oâtkazaylik, lekin date Date ga aylanadi:
let str = '{"title":"Konferensiya","date":"2017-11-30T12:00:00.000Z"}';
let meetup = JSON.parse(str, function(key, value) {
if (key == 'date') return new Date(value);
return value;
});
alert( meetup.date.getDate() ); // hozir ishlaydi!
Aytgancha, bu ichki oârnatilgan obyektlar uchun ham ishlaydi:
let schedule = `{
"meetups": [
{"title":"Conference","date":"2017-11-30T12:00:00.000Z"},
{"title":"Birthday","date":"2017-04-18T12:00:00.000Z"}
]
}`;
schedule = JSON.parse(schedule, function(key, value) {
if (key == 'date') return new Date(value);
return value;
});
alert( schedule.meetups[1].date.getDate() ); // ishlaydi!
Xulosa
- JSON â bu koâpgina dasturlash tillari uchun oâzining mustaqil standarti va kutubxonalariga ega boâlgan maâlumotlar formati.
- JSON oddiy obyektlar, massivlar, satrlar, raqamlar, mantiqiy turdagi qiymatlar va
nullni qoâllab-quvvatlaydi. - JavaScript-da JSON-ga seriyalash uchun JSON.stringify va JSON-dan oâqish uchun JSON.parse usullari mavjud.
- Ikkala usul ham aqlli oâqish/yozish uchun transformator funktsiyalarini qoâllab-quvvatlaydi.
- Agar obyektda
toJSONboâlsa, u holdaJSON.stringifytomonidan chaqiriladi.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)