Mundarija (40)
- Bu darsda
- 1. Nega bu kerak?
- 2. space: chiroyli chiqarish
- 2.1 Chekinish soni
- 2.2 Son yoki satr
- 3. Replacer massivi: faqat kerakli maydonlar
- 3.1 Oq ro'yxat
- 3.2 Tuzoq: ro'yxat hamma darajaga ta'sir qiladi
- 4. Replacer funksiyasi: har qiymatni o'zgartirish
- 4.1 Callback (kalit, qiymat)
- 4.2 Qiymatni o'zgartirish va o'chirish
- 4.3 Eng muhim qoida: oxirida return qiymat
- 5. toJSON: obyekt o'zini qanday yozishni o'zi aytadi
- 5.1 Sana nega satr bo'lib qoladi
- 5.2 O'z toJSON ingiz
- 6. Reviver: o'qishda qiymatni tiklash
- 6.1 Sana qaytib keladi
- 6.2 Tartib: ichkaridan tashqariga
- 6.3 undefined qaytarsa — o'chiriladi
- 7. JSON chegaralari: nima sig'maydi
- 7.1 Jadval
- 7.2 Aylanma havola
- 8. Katta sonlar: JSON.rawJSON va manba matni
- 8.1 Muammo: son "buziladi"
- 8.2 Yechim: reviver'ning uchinchi argumenti
- 8.3 Teskari yo'l: JSON.rawJSON
- 9. Qaysi vositani qachon ishlatish
- 10. Ko'p uchraydigan xatolar
- 10.1 Replacer massivida tashqi kalit yo'q
- 10.2 Callback return qiymat siz tugaydi
- 10.3 Sanani kalitsiz "taxmin qilish"
- 10.4 Map ni to'g'ridan-to'g'ri yozish
- 11. Mashqlar
- 1-mashq (oson): Chiroyli menyu
- 2-mashq (o'rta): Mehmon uchun menyu
- 3-mashq (qiyin): Borib-qaytgan buyurtma
- 4-mashq: Vazifalar qadami — eksport formatini yaxshilash
- 12. Real ishda
- Xulosa
- Manbalar
JSON chuqur: replacer, reviver, toJSON va JSON chegaralari
Qisqacha:
JSON.stringify(qiymat, replacer, space)uch argument oladi.spacematnni chiroyli chekinish bilan yozadi,replaceresa qaysi maydon va qanday ko'rinishda yozilishini hal qiladi. Teskari yo'ldaJSON.parse(matn, reviver)dagirevivero'qilgan har qiymatni o'zgartira oladi — masalan, satrni qaytadan sanaga aylantiradi.undefined, funksiya,Symbol,Map,SetJSON'ga sig'maydi,BigIntva aylanma havola esaTypeErrorberadi.
Bu darsda
spacebilan JSON'ni odam o'qiydigan ko'rinishda chiqarasiz.replacermassivi bilan faqat kerakli maydonlarni, funksiyasi bilan esa o'zgartirilgan qiymatlarni yozasiz.toJSONmetodi obyektning JSON ko'rinishini qanday belgilashini tushuntira olasiz.reviverbilan sanani va katta sonni to'g'ri tiklaysiz.- JSON'ga sig'maydigan turlarni va aylanma havola xatosini oldindan bilasiz.
Oldin bilishingiz kerak: JSON asoslari, BigInt: juda katta butun sonlar, Callback va HOF.
1. Nega bu kerak?
JSON asoslari darsida vazifalar ga eksport qo'shdik. Natija ishlaydi, lekin uch vazifa bitta uzun qatorga tiqilib ketdi. O'n vazifa bo'lsa, uni ko'z bilan o'qib bo'lmaydi.
Bu — birinchi muammo. Yana uchtasi bor:
- Jasur aka menyuni mehmonlar saytiga JSON qilib beradi. Menyu obyektida tannarx ham bor — taom o'ziga necha pulga tushishi. Mehmon buni ko'rmasligi kerak.
- Buyurtma sanasi JSON'dan qaytganda — sana emas, oddiy satr.
- To'lov raqami
BigIntda.stringifyungaTypeErrorberadi (BigInt).
stringify va parse ning hozirgacha ishlatmagan argumentlari aynan shular uchun. Ular — o'zingiz beradigan sozlamalar va callback'lar.
2. space: chiroyli chiqarish
2.1 Chekinish soni
stringify ning uchinchi argumenti — chekinish. Ikkinchisini hozircha null qilib qo'yamiz:
const buyurtma = { stol: 4, taomlar: ["Osh", "Manti"] };
console.log(JSON.stringify(buyurtma, null, 2));Konsolda:
{
"stol": 4,
"taomlar": [
"Osh",
"Manti"
]
}2 — har ichki daraja ikki bo'sh joy bilan suriladi. Har kalit va har massiv elementi alohida qatorda. jq ning chiqishiga o'xshaydi (JSON: dasturlar tili).
2.2 Son yoki satr
space son bo'lsa — shuncha bo'sh joy, 10 dan ko'pi kesiladi. Satr bo'lsa — chekinish o'rniga shu satrning o'zi qo'yiladi:
const taom = { nom: "Osh", narx: 35000 };
console.log(JSON.stringify(taom, null, "\t"));
const keng = JSON.stringify(taom, null, 20);
console.log(keng === JSON.stringify(taom, null, 10)); // trueKonsolda:
{
"nom": "Osh",
"narx": 35000
}
true"\t" — tab belgisi. Ko'p loyihalarda chekinish 2 bo'sh joy, shuning uchun 2 eng ko'p uchraydi.
space faqat ko'rinishni o'zgartiradi. parse uchun bo'sh joy va yangi qatorlar ahamiyatsiz: ixcham va chiroyli matn bir xil obyektga aylanadi. Tarmoqqa yuborishda bo'sh joysiz (ixcham) yozing — kamroq bayt. Odam o'qiydigan joyda — fayl, log, eksport — 2.
Tekshirib ko'ring:
JSON.parse(JSON.stringify(x, null, 2))vaJSON.parse(JSON.stringify(x))— natijalar farq qiladimi?
Javob
Yo'q. Chekinish — faqat matndagi bo'sh joy va yangi qatorlar. parse ularni o'tkazib yuboradi. Ikkala holatda ham bir xil tuzilmali yangi obyekt chiqadi.
3. Replacer massivi: faqat kerakli maydonlar
3.1 Oq ro'yxat
Ikkinchi argument — replacer ("almashtiruvchi"). U massiv bo'lsa — faqat shu kalitlar yoziladi. Qolganlari tashlab yuboriladi:
const menyu = [
{ nom: "Osh", narx: 35000, tannarx: 21000 },
{ nom: "Manti", narx: 30000, tannarx: 17000 },
];
console.log(JSON.stringify(menyu, ["nom", "narx"]));Konsolda:
[{"nom":"Osh","narx":35000},{"nom":"Manti","narx":30000}]tannarx mehmonga ketmadi. Bu — oq ro'yxat (whitelist): "faqat shularga ruxsat". Teskarisi — qora ro'yxat: "shulardan tashqari hammasi". Ma'lumot tashqariga chiqadigan joyda oq ro'yxat xavfsizroq. Ertaga obyektga yangi maxfiy maydon qo'shilsa ham, u o'z-o'zidan tashqariga chiqib ketmaydi.
3.2 Tuzoq: ro'yxat hamma darajaga ta'sir qiladi
Endi menyuni obyekt ichiga o'raymiz:
const menyu = [
{ nom: "Osh", narx: 35000, tannarx: 21000 },
{ nom: "Manti", narx: 30000, tannarx: 17000 },
];
const paket = { taomlar: menyu };
console.log(JSON.stringify(paket, ["nom", "narx"])); // {}Bo'sh obyekt! Ro'yxat har darajadagi kalitlarga qo'llanadi. Eng tashqi obyektda taomlar kaliti bor, u esa ro'yxatda yo'q — shuning uchun butun massiv tushib qoldi. Tuzatish — tashqi kalitni ham ro'yxatga qo'shish:
const menyu = [{ nom: "Osh", narx: 35000, tannarx: 21000 }];
const paket = { taomlar: menyu };
const ruxsat = ["taomlar", "nom", "narx"];
console.log(JSON.stringify(paket, ruxsat));Konsolda:
{"taomlar":[{"nom":"Osh","narx":35000}]}Massiv elementlariga (0, 1, ...) ro'yxat ta'sir qilmaydi — ular doim yoziladi. Faqat obyekt kalitlari tekshiriladi.
Replacer massivi va space birga ishlaydi: JSON.stringify(paket, ruxsat, 2).
4. Replacer funksiyasi: har qiymatni o'zgartirish
4.1 Callback (kalit, qiymat)
Replacer funksiya bo'lsa — stringify uni har kalit-qiymat juftligi uchun chaqiradi. Bu yana bir HOF: sikl stringify ichida, siz faqat callback berasiz (Callback va HOF). Callback nima qaytarsa — JSON'ga shu yoziladi:
const buyurtma = { stol: 4, taom: { nom: "Osh", narx: 35000 } };
const matn = JSON.stringify(buyurtma, (kalit, qiymat) => {
console.log(`«${kalit}» → ${typeof qiymat}`);
return qiymat;
});
console.log(matn);Konsolda:
«» → object
«stol» → number
«taom» → object
«nom» → string
«narx» → number
{"stol":4,"taom":{"nom":"Osh","narx":35000}}Uchta narsaga qarang:
- Birinchi chaqiruv — bo'sh kalit
""bilan, qiymati esa butun obyekt. Bu — ildiz (root): eng tashqi qiymat, qolgan hamma narsa daraxt shoxlaridek undan o'sib chiqadi.stringifyavval aynan uni callback'dan o'tkazadi. - Keyin tashqaridan ichkariga:
taomobyekti, so'ng uning ichidaginomvanarx. - Callback qiymatni o'zgarishsiz qaytardi — natija oddiy
stringifybilan bir xil.
4.2 Qiymatni o'zgartirish va o'chirish
Callback qaytargan qiymat asl qiymat o'rniga yoziladi. undefined qaytarsa — kalit butunlay tushib qoladi. Ikkalasini birga ishlatamiz: tannarx ni yashiramiz va to'lov raqamini (BigInt) satrga aylantiramiz:
const tolov = {
raqam: 9007199254740993123n,
taom: "Osh",
summa: 35000,
tannarx: 21000,
};
function tayyorla(kalit, qiymat) {
if (kalit === "tannarx") {
return undefined;
}
if (typeof qiymat === "bigint") {
return qiymat.toString();
}
return qiymat;
}
console.log(JSON.stringify(tolov, tayyorla));Konsolda:
{"raqam":"9007199254740993123","taom":"Osh","summa":35000}BigInt darsida va'da qilgan edik: "BigInt'ni avtomatik satrga aylantirish usuli bor". Mana u — replacer. Endi har BigInt qayerda bo'lmasin, o'zi satrga aylanadi. Qabul qiluvchi tomon uni BigInt("...") bilan tiklaydi.
4.3 Eng muhim qoida: oxirida return qiymat
const taom = { nom: "Osh", tannarx: 21000 };
const matn = JSON.stringify(taom, (kalit, qiymat) => {
if (kalit !== "tannarx") {
return qiymat;
}
});
console.log(matn); // {"nom":"Osh"}Bu ishladi. Lekin if ichidagi return ni unutsangiz — ildiz chaqiruvi ("") ham undefined qaytaradi va butun natija undefined bo'ladi. Callback'ning oxirgi qatori deyarli doim return qiymat; bo'lsin — "boshqa hamma narsa o'zgarishsiz".
Tekshirib ko'ring:
JSON.stringify({ a: 1, b: 2 }, (k, v) => (typeof v === "number" ? v * 10 : v))nima qaytaradi?
Javob
{"a":10,"b":20}. Ildiz chaqiruvida qiymat obyekt — u o'zgarishsiz qaytdi. a va b da qiymat son — o'n barobar qilindi. Callback har qiymat uchun chaqiriladi va uning javobi JSON'ga yoziladi.
5. toJSON: obyekt o'zini qanday yozishni o'zi aytadi
5.1 Sana nega satr bo'lib qoladi
JSON asoslari da sana JSON'dan satr bo'lib qaytishini ko'rdik. Sababi — toJSON metodi. stringify har obyektdan so'raydi: "senda toJSON metodi bormi?" Bor bo'lsa — obyektning o'rniga shu metod qaytargan qiymatni yozadi.
Sana — Date obyekti. U sana va vaqtni saqlaydi; uni Date asoslari darsida o'rganamiz — hozir bilish shart emas. Uning toJSON metodi bor:
const sana = new Date("2026-10-04T09:30:00Z");
console.log(sana.toJSON()); // 2026-10-04T09:30:00.000Z
const matn = JSON.stringify({ sana });
console.log(matn); // {"sana":"2026-10-04T09:30:00.000Z"}toJSON sanani ISO 8601 ko'rinishidagi satrga aylantiradi — JSON: dasturlar tili darsidagi xalqaro sana formati. stringify shu satrni yozdi.
5.2 O'z toJSON ingiz
Istalgan obyektga toJSON metodini qo'shish mumkin. To'lov kartasini JSON'ga yozganda raqamning faqat oxirgi 4 ta raqami ko'rinsin:
const karta = {
egasi: "Ali",
raqam: "8600 0000 0000 1234",
toJSON() {
return {
egasi: karta.egasi,
raqam: "**** " + karta.raqam.slice(-4),
};
},
};
console.log(JSON.stringify({ tolov: karta }));Konsolda:
{"tolov":{"egasi":"Ali","raqam":"**** 1234"}}Karta to'liq raqami hech qanday logga yoki eksportga tushmaydi — obyekt o'zi shunday qaror qildi. toJSON ichida obyekt nomi (karta) bilan murojaat qildik. Haqiqiy kodda bu yerda this degan maxsus so'z yoziladi — uni this: to'rt qoida darsida o'rganamiz. toJSON ayniqsa klasslarda ko'p uchraydi.
toJSON va replacer birga bo'lsa — avval toJSON, keyin replacer ishlaydi. Ya'ni replacer Date obyektini emas, allaqachon tayyor satrni ko'radi.
6. Reviver: o'qishda qiymatni tiklash
6.1 Sana qaytib keladi
JSON.parse ning ikkinchi argumenti — reviver ("jonlantiruvchi"). Bu ham (kalit, qiymat) callback: parse har o'qilgan qiymatni undan o'tkazadi. Callback qaytargani natijaga yoziladi:
const matn = '{"stol":4,"sana":"2026-10-04T09:30:00.000Z"}';
const oddiy = JSON.parse(matn);
console.log(typeof oddiy.sana); // string
const buyurtma = JSON.parse(matn, (kalit, qiymat) => {
if (kalit === "sana") {
return new Date(qiymat);
}
return qiymat;
});
console.log(buyurtma.sana.toISOString()); // 2026-10-04T09:30:00.000Z
console.log(typeof buyurtma.sana.getTime); // functionReviver'siz sana — satr. Reviver bilan — yana sana obyekti, uning metodlari bilan: toISOString() sanani ISO satrga qaytaradi, getTime esa — funksiya. Satrda bunday metodlar yo'q. Qaysi kalit sana ekanini siz bilasiz va aytasiz: JSON'ning o'zi bu ma'lumotni saqlamaydi.
6.2 Tartib: ichkaridan tashqariga
Reviver'ning chaqirilish tartibi replacer'nikiga teskari. Avval eng ichki qiymatlar, ildiz — eng oxirida. Keyingi tugmasini bosib kuzating:
Bu tartib qulay: obyekt reviver'ga yetib kelganda, uning ichidagi sanalar allaqachon tiklangan bo'ladi.
6.3 undefined qaytarsa — o'chiriladi
Replacer'dagidek: reviver undefined qaytarsa, kalit natijadan o'chiriladi. Ildizda undefined qaytsa — parse ning o'zi undefined qaytaradi. Shuning uchun reviver ham doim return qiymat; bilan tugasin.
Tekshirib ko'ring:
JSON.parse('{"a":1,"b":2}', (k, v) => { if (k === "a") return v; })nima qaytaradi?
Javob
undefined. a uchun 1 qaytdi, b uchun — undefined (o'chirildi). Lekin ildiz ("") uchun ham undefined qaytdi, chunki shart faqat "a" ni tekshiradi. Ildiz natijasi — butun parse natijasi.
7. JSON chegaralari: nima sig'maydi
7.1 Jadval
JSON'da faqat oltita tur bor. Qolgan JavaScript qiymatlari bilan stringify shunday ishlaydi (Node 24 da tekshirilgan):
| Qiymat | Obyekt ichida | Massiv ichida |
|---|---|---|
undefined, funksiya, Symbol |
Kalit tushib qoladi | null |
NaN, Infinity |
null |
null |
-0 |
0 |
0 |
Date |
ISO satr (toJSON) |
ISO satr |
Map, Set |
{} |
{} |
BigInt |
TypeError |
TypeError |
Symbol — noyob identifikator turi (Symbol), Map va Set — maxsus to'plamlar (Map, Set). Ularni shu qismda o'rganamiz, hozir faqat jadvaldagi xulqni eslab qoling. Massivda nega null? Element tushib qolsa, keyingilarning indeksi siljib ketardi. null o'rinni saqlab qoladi:
const qiymatlar = [1, undefined, () => 2, NaN, -0];
console.log(JSON.stringify(qiymatlar)); // [1,null,null,null,0]Eng xavflisi — Map va Set. Ichi to'la bo'lsa ham {} bo'lib qoladi, xatosiz. Ma'lumot jimgina yo'qoladi. Ularni JSON'ga yozishdan oldin oddiy massiv yoki obyektga aylantirish kerak — usulini o'sha darslarda ko'rasiz.
7.2 Aylanma havola
Bobur — doimiy mehmon. Uning obyektida buyurtmalari, har buyurtmada esa mijozning o'zi bor:
const mijoz = { ism: "Bobur", buyurtmalar: [] };
const buyurtma = { taom: "Osh", mijoz };
mijoz.buyurtmalar.push(buyurtma);
JSON.stringify(mijoz);TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'buyurtmalar' -> object with constructor 'Array'
| index 0 -> object with constructor 'Object'
--- property 'mijoz' closes the circleTarjimasi: "Aylanma tuzilmani JSON'ga aylantirib bo'lmaydi". Keyingi qatorlar yo'lni ko'rsatadi: mijozdan boshlab → buyurtmalar massivi → 0-element → uning mijoz xususiyati doirani yopdi. stringify buni yozishga harakat qilsa, cheksiz aylanib qolardi: mijoz → buyurtma → mijoz → ...
Aylanma havola (circular reference) — obyekt zanjir bo'ylab o'ziga qaytib havola qilishi. Yechim — ma'lumotni JSON uchun "tekislash": buyurtmada butun mijoz emas, faqat uning id si yoki ismi tursin:
const mijoz = { ism: "Bobur", buyurtmalar: [] };
const buyurtma = { taom: "Osh", mijoz: mijoz.ism };
mijoz.buyurtmalar.push(buyurtma);
console.log(JSON.stringify(mijoz));Konsolda:
{"ism":"Bobur","buyurtmalar":[{"taom":"Osh","mijoz":"Bobur"}]}Ma'lumotlar bazalari ham aynan shunday ishlaydi: jadvallar bir-biriga id orqali bog'lanadi, obyektning o'zi orqali emas (bazalar — kursning backend qismida).
Tekshirib ko'ring:
JSON.stringify({ taomlar: new Set(["osh", "manti"]) })nima qaytaradi? Xato chiqadimi?
Javob
{"taomlar":{}} — xatosiz. Set ning ichidagi qiymatlar oddiy xususiyat emas, stringify ularni ko'rmaydi va bo'sh obyekt yozadi. Xato chiqmagani uchun bu juda xavfli: ma'lumot jimgina yo'qoladi.
8. Katta sonlar: JSON.rawJSON va manba matni
8.1 Muammo: son "buziladi"
Ba'zi tizimlar ID'ni juda katta son qilib yuboradi. JSON standarti son uzunligini cheklamaydi, JavaScript'ning Number i esa faqat 2⁵³ gacha aniq (Number turi):
const matn = '{"id": 12345678901234567890}';
console.log(JSON.parse(matn).id); // 12345678901234567000Oxirgi raqamlar 000 bo'lib qoldi. parse xato bermadi — sonni o'qib, eng yaqin Number ga yaxlitladi. Reviver ham yordam bermaydi: unga allaqachon buzilgan son keladi.
8.2 Yechim: reviver'ning uchinchi argumenti
Yangi brauzerlar va Node 24 da reviver uchinchi argument ham oladi — context obyekti. Unda source bor: qiymatning matndagi asl yozuvi:
const matn = '{"id": 12345678901234567890, "soni": 2}';
const natija = JSON.parse(matn, (kalit, qiymat, context) => {
if (kalit === "id") {
return BigInt(context.source);
}
return qiymat;
});
console.log(natija.id); // 12345678901234567890n
console.log(natija.soni); // 2context.source — "12345678901234567890" satri, yaxlitlanmagan. Undan BigInt yasadik — son to'liq saqlandi. source faqat oddiy qiymatlarda (son, satr, true/false/null) bo'ladi, obyekt va massivda yo'q.
8.3 Teskari yo'l: JSON.rawJSON
Yozishda ham shu muammo bor. BigInt ni satrga aylantirsak — "12345...", qo'shtirnoq bilan. Server esa qo'shtirnoqsiz son kutishi mumkin. JSON.rawJSON(matn) — "bu matnni JSON'ga o'zgartirmasdan qo'y" degan belgi:
const tolov = { id: 12345678901234567890n, summa: 35000 };
const matn = JSON.stringify(tolov, (kalit, qiymat) => {
if (typeof qiymat === "bigint") {
return JSON.rawJSON(qiymat.toString());
}
return qiymat;
});
console.log(matn); // {"id":12345678901234567890,"summa":35000}id qo'shtirnoqsiz, barcha raqamlari bilan yozildi. JSON.rawJSON faqat oddiy qiymat matnini qabul qiladi (son, satr, true, false, null) — u orqali obyekt yoki massiv qo'yib bo'lmaydi.
Maslahat:
JSON.rawJSONva reviver'ningcontextargumenti — yangi imkoniyat. Baseline ma'lumotiga ko'ra ular 2025-yil 31-martdan beri Baseline (Chrome 114, Firefox 135, Safari 18.4); Node 24 da ishlaydi. Eski brauzerlarni ham qo'llash kerak bo'lsa — katta ID'larni satr qilib yuboring.
Tekshirib ko'ring: Server katta ID'larni qo'shtirnoqli satr qilib yuboradi:
{"id": "12345678901234567890"}. Bu holdacontext.sourcekerakmi?
Javob
Kerak emas. Satr hech qachon yaxlitlanmaydi — parse uni barcha raqamlari bilan qaytaradi. Reviver'da oddiy BigInt(qiymat) yetarli. context.source faqat katta son qo'shtirnoqsiz kelganda — ya'ni Number ga aylantirilib, buzilib ketadigan holatda — kerak.
9. Qaysi vositani qachon ishlatish
| Vazifa | Vosita |
|---|---|
| Odam o'qiydigan chiqish | space (2) |
| Faqat ruxsat etilgan maydonlar | Replacer massivi |
| Qiymatni o'zgartirish yoki yashirish | Replacer funksiyasi |
| Obyekt o'zini qanday yozishini o'zi biladi | toJSON |
O'qishda sana, BigInt ni tiklash |
Reviver |
| Katta sonni aniq o'qish/yozish | context.source, JSON.rawJSON |
Ko'pincha ikkitasi birga ishlaydi: yozishda replacer yoki toJSON, o'qishda — ularga mos reviver. Ikki tomon bitta kelishuvga amal qilishi kerak: "sana — ISO satr", "ID — satr". Bu kelishuv odatda API hujjatida yoziladi.
10. Ko'p uchraydigan xatolar
10.1 Replacer massivida tashqi kalit yo'q
«Replacer massivi» bo'limidagi {} natija. Ro'yxat har darajaga qo'llanadi. Tuzatish: tashqi kalitlarni ham ("taomlar") ro'yxatga yozing va natijani bir marta ko'z bilan tekshiring.
10.2 Callback return qiymat siz tugaydi
const taom = { nom: "Osh", narx: 35000 };
const matn = JSON.stringify(taom, (kalit, qiymat) => {
if (kalit === "narx") {
return `${qiymat} so'm`;
}
});
console.log(matn); // undefinedNatija — matn emas, undefined. Ildiz chaqiruvida ("") hech qanday return ishlamadi. Reviver'da ham xuddi shunday. Tuzatish: oxirgi qator — return qiymat;.
10.3 Sanani kalitsiz "taxmin qilish"
Ba'zan reviver har satrni sana deb tekshiradi: "ISO ko'rinishida bo'lsa — sanaga aylantir". Lekin mehmon izohga 2026-10-04T09:30:00Z deb yozsa, u ham sanaga aylanib ketadi. Tuzatish: sanani kalit bo'yicha tiklang (kalit === "sana") — siz ma'lumot tuzilmasini bilasiz.
10.4 Map ni to'g'ridan-to'g'ri yozish
{} — xatosiz, lekin bo'sh. Tuzatish: stringify dan oldin oddiy massiv yoki obyektga aylantiring (Map).
11. Mashqlar
1-mashq (oson): Chiroyli menyu
menyu ni 2 bo'sh joyli chekinish bilan chiqaring. Keyin xuddi shuni tab bilan chiqaring.
const menyu = { kafe: "Bahor", taomlar: ["Osh", "Manti"] };Yechim
const menyu = { kafe: "Bahor", taomlar: ["Osh", "Manti"] };
console.log(JSON.stringify(menyu, null, 2));
console.log(JSON.stringify(menyu, null, "\t"));Konsolda:
{
"kafe": "Bahor",
"taomlar": [
"Osh",
"Manti"
]
}
{
"kafe": "Bahor",
"taomlar": [
"Osh",
"Manti"
]
}Ikkinchi argument null — replacer yo'q. Uni tashlab ketib bo'lmaydi: space aynan uchinchi o'rinda bo'lishi kerak.
2-mashq (o'rta): Mehmon uchun menyu
Ichki menyudan mehmonlar sayti uchun JSON yasang: tannarx yashirilsin, narx esa "35000 so'm" ko'rinishidagi satr bo'lsin. Replacer funksiyasi bilan.
const menyu = [
{ nom: "Osh", narx: 35000, tannarx: 21000 },
{ nom: "Ko'k choy", narx: 5000, tannarx: 1200 },
];Yechim
const menyu = [
{ nom: "Osh", narx: 35000, tannarx: 21000 },
{ nom: "Ko'k choy", narx: 5000, tannarx: 1200 },
];
function mehmonUchun(kalit, qiymat) {
if (kalit === "tannarx") {
return undefined;
}
if (kalit === "narx") {
return `${qiymat} so'm`;
}
return qiymat;
}
console.log(JSON.stringify(menyu, mehmonUchun));Konsolda:
[{"nom":"Osh","narx":"35000 so'm"},{"nom":"Ko'k choy","narx":"5000 so'm"}]Oxirgi return qiymat — ildiz massiv, har taom obyekti va nom lar uchun. Usiz natija undefined bo'lardi.
3-mashq (qiyin): Borib-qaytgan buyurtma
Buyurtmani JSON'ga yozing va qaytadan o'qing. Talablar:
- Yozishda
raqam(BigInt) — qo'shtirnoqli satr, o'qishda — yanaBigInt. - O'qishda
sana— yana sana obyekti. - Oxirida tekshiring:
nusxa.raqam === asl.raqamva ikkala sananinggetTime()qiymati teng (getTime()— sanani millisekundlarga aylantiradi).
const asl = {
raqam: 9007199254740993123n,
sana: new Date("2026-10-04T09:30:00Z"),
taom: "Osh",
};Yechim
const asl = {
raqam: 9007199254740993123n,
sana: new Date("2026-10-04T09:30:00Z"),
taom: "Osh",
};
const matn = JSON.stringify(asl, (kalit, qiymat) =>
typeof qiymat === "bigint" ? qiymat.toString() : qiymat,
);
const nusxa = JSON.parse(matn, (kalit, qiymat) => {
if (kalit === "raqam") {
return BigInt(qiymat);
}
if (kalit === "sana") {
return new Date(qiymat);
}
return qiymat;
});
console.log(matn);
console.log(nusxa.raqam === asl.raqam); // true
console.log(nusxa.sana.getTime() === asl.sana.getTime()); // trueKonsolda:
{"raqam":"9007199254740993123","sana":"2026-10-04T09:30:00.000Z","taom":"Osh"}
true
trueSana uchun replacer'da hech narsa yozmadik — Date ning o'z toJSON i bor. raqam satr bo'lib ketdi, reviver uni BigInt ga qaytardi. BigInt lar === bilan qiymat bo'yicha solishtiriladi — ular primitiv. Sanalar esa obyekt, ularni getTime() orqali solishtirdik.
4-mashq: Vazifalar qadami — eksport formatini yaxshilash
feature/eksport branch'ida davom etamiz (git switch feature/eksport). Hozirgi eksport — bitta qatorli massiv. Uni yaxshilaymiz:
- Matn chiroyli bo'lsin: 2 bo'sh joy chekinish.
- Massiv obyekt ichiga o'ralsin:
{ "versiya": 1, "vazifalar": [...] }. Versiya — format raqami. Kelajakda format o'zgarsa (masalan, vazifaga teg qo'shilsa), import qiluvchi kod eski va yangi faylni ajrata oladi. - Faqat ruxsat etilgan maydonlar chiqsin:
id,matn,bajarildi. Replacer massivi bilan — oq ro'yxat.
Faqat eksportMatni o'zgaradi.
Yechim
const eksportMaydonlari = [
"versiya", "vazifalar", "id", "matn", "bajarildi",
];
function eksportMatni(vazifalar) {
const paket = { versiya: 1, vazifalar };
return JSON.stringify(paket, eksportMaydonlari, 2);
}Ro'yxatda "versiya" va "vazifalar" ham bor — «Ko'p uchraydigan xatolar» dagi tuzoqni eslang. Ularsiz natija {} bo'lardi. { versiya: 1, vazifalar } dagi vazifalar — shorthand.
Eski va yangi formatni Node'da solishtiring. Vazifaga ataylab ortiqcha maydon qo'shamiz — u eksportga tushmasligi kerak:
const eksportMaydonlari = [
"versiya", "vazifalar", "id", "matn", "bajarildi",
];
function eksportMatni(vazifalar) {
const paket = { versiya: 1, vazifalar };
return JSON.stringify(paket, eksportMaydonlari, 2);
}
const vazifalar = [
{ id: 1, matn: "Non olish", bajarildi: false, vaqtincha: "x" },
];
console.log(JSON.stringify(vazifalar));
console.log(eksportMatni(vazifalar));
console.log(JSON.parse(eksportMatni(vazifalar)).vazifalar[0].matn);Konsolda:
[{"id":1,"matn":"Non olish","bajarildi":false,"vaqtincha":"x"}]
{
"versiya": 1,
"vazifalar": [
{
"id": 1,
"matn": "Non olish",
"bajarildi": false
}
]
}
Non olishEski usul vaqtincha ni ham chiqarib yubordi, oq ro'yxat — yo'q. Yangi matn ham to'g'ri JSON: parse uni muammosiz o'qidi.
Brauzerda tekshiring:
- «JSON qilib chiqarish» — maydonda chekinishli matn, tepasida
"versiya": 1.rows="6"kichik bo'lsa, maydonni pastki burchagidan torting yokirowsni oshiring. - Vazifa qo'shing, belgilang, qayta eksport qiling — o'zgarishlar matnda. Fokus va «JSON tayyor...» e'loni — avvalgidek.
Commit va branch'ni yakunlash:
git add assets/js/vazifalar.js
git commit -m "Vazifalar: eksportga versiya va oq ro'yxat qo'sh"
git switch main
git merge feature/eksport
git branch -d feature/eksport
git pushFormat tayyor. Uni o'qiydigan import — versiya ni tekshirib, buzilgan matnni ushlaydigan — try / catch / finally darsida.
12. Real ishda
- API javoblari. Serverda foydalanuvchi obyektini mijozga yuborishdan oldin parolning shifrlangan izi (xesh), ichki izohlar kabi maydonlar olib tashlanadi. Freymvorklarda bu ko'pincha
toJSONyoki maxsus "serializer" bilan qilinadi — replacer'ning kattalashgan shakli. - Konfiguratsiya fayllari.
package.jsonni o'zgartiradigan vositalar uniJSON.stringify(obj, null, 2)bilan qayta yozadi — fayl odam o'qiydigan bo'lib qoladi. npm ham shunday qiladi. - Loglar. Xatolarni JSON qatorlari ko'rinishida yozish (NDJSON — JSON: dasturlar tili) — replacer bilan parol va token yashiriladi.
- Katta ID'lar. X (sobiq Twitter), to'lov tizimlari 64 bitli ID beradi. Ularni satr qilib yuborish — eng ishonchli yo'l;
JSON.rawJSON— yangi variant. - Intervyu. "
JSON.stringifyqanday qiymatlarni tashlab yuboradi?", "aylanma havola bilan nima qilasiz?", "sanani JSON'dan qanday tiklaysiz?" — ko'p uchraydi.
Xulosa
JSON.stringify(qiymat, replacer, space):space— chekinish (≤ 10), replacer — massiv (oq ro'yxat) yoki funksiya.- Replacer massivi har darajaga qo'llanadi — tashqi kalitlarni ham yozing.
- Replacer va reviver —
(kalit, qiymat)callback'lar: birinchi/oxirgi chaqiruv — ildiz, kaliti"".undefinedqaytsa — kalit o'chadi; oxirida doimreturn qiymat. toJSON— obyekt o'zining JSON ko'rinishini belgilaydi (Dateshunday satrga aylanadi).- Reviver bilan sanani kalit bo'yicha tiklang; katta son uchun —
context.sourcevaJSON.rawJSON. undefined/funksiya/Symboltushib qoladi,Map/Set—{},BigIntva aylanma havola —TypeError.
Keyingi dars: Execution context va call stack — endi JavaScript kodingizni qanday bajarishini ichidan ko'ramiz: har funksiya chaqiruvi qanday "kontekst" yaratadi va ular stekka qanday joylanadi.
Manbalar
- MDN: "JSON.stringify()", "JSON.parse()", "JSON.rawJSON()", "JSON.isRawJSON()" — developer.mozilla.org
- TC39: "JSON.parse source text access" taklifi — github.com/tc39/proposal-json-parse-with-source
- web-features 3.40 (npm paketi):
json-raw— Baseline 2025-03-31
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!