IlmHamroh
JavaScript Full-stack/10-qism. JavaScript chuqur17/65-dars19 daqiqa
Mundarija (32)

JSON JavaScript'da: JSON.stringify va JSON.parse asoslari

Qisqacha: JSON — ma'lumotni dasturlar orasida matn ko'rinishida tashish formati. JavaScript'da ikki funksiya bor: JSON.stringify(obyekt) obyektni JSON matniga aylantiradi, JSON.parse(matn) esa matndan yangi obyekt yasaydi. JSON JavaScript obyektiga o'xshaydi, lekin qoidalari qattiqroq: kalitlar faqat qo'shtirnoqda, oxirgi vergul, izoh, undefined va funksiya yo'q.

Bu darsda

  • JSON.stringify bilan obyekt va massivni JSON matniga aylantira olasiz.
  • JSON.parse bilan JSON matnidan yangi obyekt yasay olasiz.
  • JavaScript obyekti va JSON matnining farqini aniq ayta olasiz.
  • JSON.parse ning SyntaxError xabarlarini o'qib, matndagi xatoni topa olasiz.
  • vazifalar ilovasiga "Eksport" tugmasini qo'shasiz: ro'yxat JSON matni bo'lib chiqadi.

Oldin bilishingiz kerak: JSON: dasturlar tili, Obyekt: kalit-qiymat juftliklari, Sayoz va chuqur nusxalash, Ichma-ich ma'lumotni immutable yangilash.

1. Nega bu kerak?

«Bahor»da ofitsiant Otabek buyurtmani planshetga kiritadi. Planshetdagi JavaScript'da buyurtma — oddiy obyekt:

js
const buyurtma = { stol: 4, taom: "Osh", soni: 2 };

Bu obyekt planshet xotirasida yashaydi. Oshxonadagi Rustam akaning ekrani esa boshqa kompyuter. Xotiradagi obyektni simdan "o'tkazib" bo'lmaydi: tarmoq faqat matn (aniqrog'i, baytlar) tashiydi. Obyektni faylga yozish uchun ham avval uni matnga aylantirish kerak.

Demak ikki ish kerak:

  1. Jo'natishdan oldin — obyektni matnga aylantirish.
  2. Qabul qilgach — matndan qaytadan obyekt yasash.

Bu matnning eng mashhur formati sizga tanish. JSON: dasturlar tili darsida JSON fayllarni jq bilan o'qigan edingiz. Endi JSON'ni JavaScript'ning o'zida yaratamiz va o'qiymiz. Sxemaga qarang — ikki funksiya, ikki yo'nalish:

flowchart LR
  A["Obyekt<br/>(planshet xotirasida)"] -- "JSON.stringify" --> B["JSON matni"]
  B -- "tarmoq yoki fayl" --> C["JSON matni"]
  C -- "JSON.parse" --> D["Yangi obyekt<br/>(oshxona xotirasida)"]

Hayotdan o'xshatish: posilka. Javonni pochta orqali jo'natib bo'lmaydi — uni qismlarga ajratib, qutiga joylaysiz. Qabul qilgan odam qutini ochib, javonni qaytadan yig'adi. JSON.stringify — qutiga joylash, JSON.parse — qutidan chiqarib yig'ish. Yig'ilgan javon xuddi o'shanday, lekin bu boshqa javon.

2. JSON — bu matn

2.1 JS obyekti va JSON yonma-yon

Avval eng muhim fikr: JSON — satr. U obyektga o'xshab ko'rinadi, lekin JavaScript uchun bu shunchaki belgilar ketma-ketligi:

js
const obyekt = { taom: "Osh", narx: 35000 };
const matn = '{"taom":"Osh","narx":35000}';

console.log(typeof obyekt); // object
console.log(typeof matn); // string
console.log(obyekt.narx); // 35000
console.log(matn.narx); // undefined
console.log(matn.length); // 27

matn.narx — undefined. Satrda narx degan xususiyat yo'q, unda faqat 27 ta belgi bor. Matndagi ma'lumotdan foydalanish uchun avval uni obyektga aylantirish kerak.

2.2 Qoidalar farqi

JavaScript obyektini yozishda erkinroqsiz. JSON qattiqroq — JSON: dasturlar tili darsidagi qoidalar:

JavaScript obyekti JSON matni
Kalit narx yoki "narx" Faqat "narx"
Satr 'osh', "osh", `osh` Faqat "osh"
Oxirgi vergul Mumkin Yo'q
Izoh // Mumkin Yo'q

Qiymat turlarida ham farq bor:

Qiymat JavaScript'da JSON'da
undefined Bor Yo'q
Funksiya Bor Yo'q
NaN, Infinity Bor Yo'q
Sana Date obyekti Faqat satr

Ya'ni JSON — JavaScript'ning qat'iy kichik qismi. Har to'g'ri JSON matni JavaScript ifodasi sifatida ham o'qiladi, lekin teskarisi to'g'ri emas. Nomi ham shundan: JSON — JavaScript Object Notation, "JavaScript obyekt yozuvi".

Tekshirib ko'ring: { narx: 35000, } — to'g'ri JS obyektimi? To'g'ri JSON'mi?

Javob

JS obyekti sifatida — to'g'ri: kalit qo'shtirnoqsiz va oxirgi vergul JavaScript'da ruxsat etilgan. JSON sifatida — ikki xato: narx qo'shtirnoqda emas, oxirida ortiqcha vergul bor. To'g'ri JSON: {"narx": 35000}.

3. JSON.stringify: obyekt → matn

3.1 Birinchi misol

JSON — JavaScript'ga o'rnatilgan obyekt, xuddi Math kabi (Math obyekti). Uning stringify metodi qiymatni JSON matniga aylantiradi:

js
const buyurtma = {
  stol: 4,
  taomlar: ["Osh", "Ko'k choy"],
  tolandi: false,
  izoh: null,
};

const matn = JSON.stringify(buyurtma);

console.log(matn);
console.log(typeof matn); // string

Konsolda:

text
{"stol":4,"taomlar":["Osh","Ko'k choy"],"tolandi":false,"izoh":null}
string

Natijaga qarang:

  • Har kalit qo'shtirnoqqa olindi: stol → "stol".
  • Satrlar qo'shtirnoqda, sonlar, false va null — qo'shtirnoqsiz. Turlar saqlandi.
  • Bo'sh joy umuman yo'q — matn imkon qadar ixcham. Tarmoq uchun bu yaxshi: kamroq bayt.
  • Ichma-ich massiv ham aylantirildi. stringify butun tuzilmani oxirigacha aylanib chiqadi.

Seriyalash (serialize) — qiymatni yuborish yoki saqlash uchun matnga aylantirish. Bu atamani BigInt darsida ko'rgan edingiz. JSON.stringify — seriyalashning eng ko'p ishlatiladigan usuli.

3.2 Maxsus belgilar ekranlanadi

Satr ichida qo'shtirnoq yoki yangi qator bo'lsa, stringify ularni o'zi ekranlaydi. Eslatma: ekranlash (escaping) — maxsus belgi oldiga teskari slesh \ qo'yib, "buni oddiy belgi deb o'qi" deyish (JSON: dasturlar tili darsidagi \" va \n):

js
const izoh = {
  matn: 'Mehmon "achchiq" so\'radi\nPiyozsiz',
};

console.log(JSON.stringify(izoh));

Konsolda:

text
{"matn":"Mehmon \"achchiq\" so'radi\nPiyozsiz"}

Qo'shtirnoq \" ga, yangi qator \n ga aylandi. Apostrof ' — JSON uchun oddiy belgi, u o'zgarmadi. O'zbek harflari, kirill va emoji ham o'zgarmaydi: JSON — UTF-8 matn.

Qo'lda yig'ilgan JSON'da aynan shu ekranlash eng ko'p unutiladi. Shuning uchun JSON matnini hech qachon satrlarni qo'shib ('{"matn":"' + izoh + '"}') yasamang. stringify har belgini to'g'ri ekranlaydi.

3.3 Faqat obyekt emas

stringify ga istalgan JSON turini berish mumkin:

js
console.log(JSON.stringify(35000)); // 35000
console.log(JSON.stringify("Osh")); // "Osh"
console.log(JSON.stringify(true)); // true
console.log(JSON.stringify(null)); // null
console.log(JSON.stringify([1, 2])); // [1,2]

Ikkinchi qatorga e'tibor bering: natija — "Osh", qo'shtirnoqlari bilan. Satrning JSON ko'rinishi qo'shtirnoqni ham o'z ichiga oladi. Bu 5 belgili satr: ", O, s, h, ".

3.4 JSON'ga sig'maydigan qiymatlar

Sayoz va chuqur nusxalash darsida ko'rgan edik: JSON hamma narsani saqlay olmaydi. Qisqa eslatma:

js
const taom = {
  nom: "Osh",
  izoh: undefined,
  hisobla() {
    return 0;
  },
  chegirma: NaN,
};

console.log(JSON.stringify(taom)); // {"nom":"Osh","chegirma":null}

undefined va funksiya xususiyati jimgina tushib qoldi, NaN esa null bo'ldi. Xato chiqmadi. Bu chegaralarni va ularni boshqarish usullarini keyingi darsda — JSON chuqur — to'liq ko'ramiz.

Tekshirib ko'ring: JSON.stringify({ narx: "35000" }) va JSON.stringify({ narx: 35000 }) — natijalar qanday farq qiladi?

Javob

Birinchisi {"narx":"35000"} — qiymat satr bo'lgani uchun qo'shtirnoqda. Ikkinchisi {"narx":35000} — son, qo'shtirnoqsiz. stringify turni saqlaydi. Qabul qiluvchi tomon birinchisidan satr, ikkinchisidan son oladi.

4. JSON.parse: matn → obyekt

4.1 Birinchi misol

Endi teskari yo'l. Oshxona ekraniga matn keldi:

js
const kelgan = '{"stol":4,"taom":"Osh","soni":2,"tolandi":false}';

const buyurtma = JSON.parse(kelgan);

console.log(buyurtma.taom); // Osh
console.log(buyurtma.soni * 35000); // 70000
console.log(typeof buyurtma.soni); // number
console.log(buyurtma.tolandi); // false

JSON.parse matnni o'qidi va undan haqiqiy obyekt yasadi. Endi buyurtma.soni — son, u bilan hisob qilsa bo'ladi. tolandi — haqiqiy false, "false" satri emas.

Inglizcha parse — "tahlil qilish": matnni belgima-belgi o'qib, tuzilmasini tushunish. Dasturchilar o'zbekchada ham "parse qilish" deyishadi.

4.2 Qadamma-qadam: borib-qaytish

Ikkala funksiyani birga ishlatamiz va har qadamda nima o'zgarishini kuzatamiz. Keyingi tugmasini bosib, typeof qanday almashishiga qarang:

Oxirgi qadam muhim. nusxa va asl ichi bir xil, lekin ular ikki xil obyekt (Havola semantikasi). Posilkadan yig'ilgan javon — boshqa javon. Shuning uchun JSON.parse(JSON.stringify(x)) chuqur nusxa beradi. Lekin bu usulning tuzoqlarini bilasiz — zamonaviy kodda chuqur nusxa uchun structuredClone (Sayoz va chuqur nusxalash).

4.3 Matn ichida faqat bitta qiymat

parse ham istalgan JSON turini o'qiydi — faqat obyektni emas:

js
console.log(JSON.parse("35000") + 1); // 35001
console.log(JSON.parse('"Osh"')); // Osh
console.log(JSON.parse("[1, 2, 3]").length); // 3
console.log(JSON.parse("null")); // null

Ikkinchi qatorga qarang: '"Osh"' — tashqi bittalik tirnoq JavaScript satrini ochadi, ichki qo'shtirnoqlar esa JSON'ning o'zi. Bo'sh joylar ([1, 2, 3]) muammo emas: parse ularni o'tkazib yuboradi.

O'zingiz to'ldiring: JSON.parse('{"soni": 3}').soni * 2 ning natijasi — .

Tekshirib ko'ring: JSON.parse('{"narx":"35000"}').narx + 5000 nima beradi?

Javob

"350005000" — satr. JSON'da narx qo'shtirnoqda edi, demak parse uni satr qilib qaytardi. Satr + son — birlashtirish (Yashirin coercion). parse turni o'zi o'ylab topmaydi: matnda qanday yozilgan bo'lsa, shunday o'qiydi.

5. JSON.parse xatolari

5.1 Xato matni nimani aytadi

stringify deyarli hech qachon xato bermaydi. parse esa — tez-tez. Chunki matn ko'pincha tashqaridan keladi: foydalanuvchi yozgan, boshqa dastur yuborgan, faylda buzilgan. Matn JSON qoidalariga zid bo'lsa, parse dasturni SyntaxError bilan to'xtatadi.

Node 24 dagi haqiqiy xabarlar bilan tanishamiz. Birinchisi — eng ko'p uchraydigani, oxirgi vergul:

js
const matn = '{"taom": "Osh", "narx": 35000,}';
JSON.parse(matn);
text
SyntaxError: Expected double-quoted property name in JSON at position 30 (line 1 column 31)

Tarjimasi: "JSON'da 30-o'rinda (1-qator, 31-ustun) qo'shtirnoqli xususiyat nomi kutilgan edi". Vergul "yana bitta juftlik keladi" degani. parse keyingi kalitni — "..." ni — kutdi, lekin } ni ko'rdi.

Xabarning ikkinchi qismi — eng foydalisi. Position (o'rin) — xato belgisining indeksi, 0 dan sanaladi, xuddi satr indeksidek (String asoslari). Column (ustun) esa 1 dan sanaladi. Bitta qatorli matnda ular doim bittaga farq qiladi. Tekshirib ko'ring: matn[30] — }.

5.2 Boshqa tipik xabarlar

Qo'shtirnoqsiz kalit — JavaScript odati bilan yozilgan "JSON":

js
JSON.parse("{taom: 'Osh'}");
text
SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)

Tarjimasi: "1-o'rinda xususiyat nomi yoki } kutilgan edi". { dan keyin " kelishi kerak edi, t keldi. Bittalik tirnoqli 'taom' ham aynan shu xatoni beradi.

Vergul unutilgan:

js
JSON.parse('{"taom": "Osh" "narx": 35000}');
text
SyntaxError: Expected ',' or '}' after property value in JSON at position 15 (line 1 column 16)

Tarjimasi: "xususiyat qiymatidan keyin , yoki } kutilgan edi". "Osh" dan keyin yangi kalit boshlandi, orada vergul yo'q.

Bo'sh matn:

js
JSON.parse("");
text
SyntaxError: Unexpected end of JSON input

Tarjimasi: "JSON kirishi kutilmaganda tugadi". Bo'sh satrda o'qiydigan narsa yo'q. Foydalanuvchi bo'sh matn maydonini yuborganda aynan shu chiqadi. Xuddi shu xabar yarim kelgan matnda ham chiqadi — masalan, internet uzilib, javobning faqat boshi kelganda.

Va eng g'alati ko'rinadigani:

js
const buyurtma = { taom: "Osh" };
JSON.parse(buyurtma);
text
SyntaxError: "[object Object]" is not valid JSON

Tarjimasi: "[object Object] — yaroqli JSON emas". Biz parse ga matn emas, obyekt berdik. parse har doim satr kutadi, shuning uchun obyektni avval satrga aylantirdi. Obyektning satr ko'rinishi esa — "[object Object]" (Turlarni aniq o'zgartirish). Bu xabarni ko'rsangiz, bilingki: allaqachon obyekt bo'lgan narsani qayta parse qilyapsiz.

Sxemada — parse matnni qanday tekshirishi. Har shoxdagi yozuv — shu yo'lda chiqadigan xabar:

flowchart TD
  A["JSON.parse(qiymat)"] --> B{"Satrmi?"}
  B -- "yo'q" --> C["Satrga aylantiradi<br/>([object Object])"]
  C --> D
  B -- "ha" --> D{"Bo'shmi?"}
  D -- "ha" --> E["Unexpected end<br/>of JSON input"]
  D -- "yo'q" --> F{"Qoidalarga mosmi?"}
  F -- "yo'q" --> G["Expected ... at position N"]
  F -- "ha" --> H["Yangi qiymat"]

5.3 Xatoni ushlash — keyinroq

Hozircha SyntaxError dasturni to'xtatadi. Brauzerda bitta ish to'xtaydi, Node'da — butun dastur (Stack trace va xato turlari). Xatoni "ushlab", foydalanuvchiga tushunarli xabar ko'rsatish uchun try...catch kerak. Uni try / catch / finally darsida o'rganamiz — hozir bilish shart emas.

Hozir qo'lingizdan keladigan bitta himoya bor: bo'sh matnni oldindan tekshirish.

js
const kiritilgan = "   ";

if (kiritilgan.trim() === "") {
  console.log("Matn bo'sh — JSON kiriting.");
} else {
  console.log(JSON.parse(kiritilgan));
}

Konsolda:

text
Matn bo'sh — JSON kiriting.

Bu faqat bitta holatni ushlaydi. Buzilgan JSON'ni oldindan "ko'z bilan" tekshirib bo'lmaydi — u uchun try...catch.

Tekshirib ko'ring: JSON.parse('{"a": 1} // izoh') qanday xato beradi deb o'ylaysiz? Nega?

Javob

SyntaxError: Unexpected non-whitespace character after JSON at position 9 (line 1 column 10) — "JSON'dan keyin bo'sh joy bo'lmagan belgi". {"a": 1} to'liq va to'g'ri JSON, u 9-o'rinda tugadi. Lekin undan keyin yana belgilar (//) bor. JSON'da izoh yo'q, matnda esa faqat bitta qiymat bo'lishi kerak.

6. Brauzerda: buyurtma qanday jo'natiladi

Planshetdagi oddiy forma: taom va sonini tanlab, savatga qo'shasiz. Pastdagi blok — serverga ketadigan matn. Har bosishda u qaytadan stringify qilinadi:

html
<style>
  body { margin: 1rem; font: 1rem/1.5 system-ui, sans-serif; }
  select, input, button { font: inherit; min-height: 2.75rem; }
  input { width: 4rem; }
  pre {
    padding: 0.75rem;
    background: #f7faf8;
    border: 1px solid #c9d6cf;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
  }
</style>
<form id="forma">
  <label for="taom">Taom</label>
  <select id="taom">
    <option>Osh</option>
    <option>Lag'mon</option>
    <option>Manti</option>
    <option>Ko'k choy</option>
  </select>
  <label for="soni">Soni</label>
  <input id="soni" type="number" min="1" max="20" value="1">
  <button type="submit">Savatga</button>
</form>
<p>Serverga ketadigan JSON:</p>
<pre id="json"></pre>
<script>
  const savat = { stol: 4, taomlar: [] };
  const forma = document.getElementById("forma");
  const jsonBlok = document.getElementById("json");

  function chiz() {
    jsonBlok.textContent = JSON.stringify(savat);
  }

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    savat.taomlar.push({
      nom: document.getElementById("taom").value,
      soni: Number(document.getElementById("soni").value),
    });
    chiz();
  });

  chiz();
  console.log(jsonBlok.textContent);
</script>

Konsolda:

text
{"stol":4,"taomlar":[]}

Sinab ko'ring:

  • «Savatga» ni bosing — taomlar massiviga {"nom":"Osh","soni":1} qo'shiladi.
  • "Lag'mon" ni tanlang, sonini 3 qiling va qo'shing. soni qo'shtirnoqsiz — 3: biz uni Number(...) bilan songa aylantirdik (Forma qiymatlarini o'qish). Number ni olib tashlasangiz, JSON'da "3" paydo bo'ladi — server satr oladi.
  • "Ko'k choy" dagi apostrof JSON'da o'zgarmaydi — u qo'shtirnoq emas.

Bu yerda savat — holat, pre dagi matn esa undan hisoblanadi (Holatdan UI chizish). Haqiqiy ilovada shu matn fetch bilan serverga yuboriladi. fetch ni 11-qismda o'rganamiz.

7. Ko'p uchraydigan xatolar

7.1 Obyektni qayta parse qilish

«JSON.parse xatolari» bo'limidagi "[object Object]" is not valid JSON. Bu ko'pincha kutubxona yoki boshqa funksiya JSON'ni allaqachon o'qib bergan holatda chiqadi. Tuzatish: console.log(typeof qiymat) bilan tekshiring. object bo'lsa — parse kerak emas.

7.2 Ikki marta stringify

js
const taom = { nom: "Osh" };
const birinchi = JSON.stringify(taom);
const ikkinchi = JSON.stringify(birinchi);

console.log(birinchi); // {"nom":"Osh"}
console.log(ikkinchi); // "{\"nom\":\"Osh\"}"

Xato chiqmadi, lekin ikkinchi natija — obyekt emas, satrning JSON'i. Uni parse qilgan tomon obyekt emas, satr oladi va qiymat.nom — undefined. Tuzatish: har qiymatni bir marta seriyalang. Matnda \" ko'p bo'lsa — ikki marta stringify qilinganiga shubha qiling.

7.3 parse qilishni unutish

«JSON — bu matn» bo'limidagi matn.narx — undefined. Matnni obyektdek ishlatish xato bermaydi, faqat undefined qaytaradi. Tuzatish: tashqaridan kelgan JSON'ni ishlatishdan oldin bir marta JSON.parse qiling.

7.4 JSON matnlarini solishtirish

js
const a = JSON.stringify({ taom: "Osh", soni: 2 });
const b = JSON.stringify({ soni: 2, taom: "Osh" });

console.log(a === b); // false

Ma'no bir xil, lekin kalitlar tartibi boshqa — matnlar boshqa. stringify kalitlarni obyektdagi tartibda yozadi (Obyekt bo'ylab yurish). Tuzatish: ikki obyektni JSON matni orqali solishtirmang — xususiyatlarni alohida solishtiring.

8. Mashqlar

1-mashq (oson): Menyu matni

menyu massivini JSON matniga aylantiring. Chiqaring: matnning o'zi, uning turi va uzunligi (length).

js
const menyu = [
  { nom: "Osh", narx: 35000 },
  { nom: "Ko'k choy", narx: 5000 },
];
Yechim
js
const menyu = [
  { nom: "Osh", narx: 35000 },
  { nom: "Ko'k choy", narx: 5000 },
];

const matn = JSON.stringify(menyu);
console.log(matn);
console.log(typeof matn); // string
console.log(matn.length); // 60

Konsolda:

text
[{"nom":"Osh","narx":35000},{"nom":"Ko'k choy","narx":5000}]
string
60

Natija [ bilan boshlanadi — tashqi qiymat massiv. Uzunlik — belgilar soni: matn tarmoqda shuncha joy egallaydi (o'zbek lotin harflari bir baytdan).

2-mashq (o'rta): Xabarni o'qing

Uchta "JSON" matni bor. Har birini JSON.parse qilib ko'ring (har birini alohida — birinchi xato dasturni to'xtatadi). Xato xabarini o'qib, matnni tuzating:

js
const a = '{"ism": "Malika", "stol": 7,}';
const b = "{'ism': 'Bobur'}";
const c = '{"ism": "Ali" "stol": 2}';

Ishora: xabardagi position — xato belgisining indeksi; a[28] kabi o'zingiz tekshiring.

Yechim

Xabarlar (Node 24):

text
a: Expected double-quoted property name in JSON at position 28 (line 1 column 29)
b: Expected property name or '}' in JSON at position 1 (line 1 column 2)
c: Expected ',' or '}' after property value in JSON at position 14 (line 1 column 15)

Har biri boshida SyntaxError: bilan chiqadi. Sabablari: a — 7 dan keyin ortiqcha vergul; b — bittalik tirnoq; c — "Ali" dan keyin vergul yo'q. Tuzatilgani:

js
const a = '{"ism": "Malika", "stol": 7}';
const b = '{"ism": "Bobur"}';
const c = '{"ism": "Ali", "stol": 2}';

console.log(JSON.parse(a).stol); // 7
console.log(JSON.parse(b).ism); // Bobur
console.log(JSON.parse(c).stol); // 2

b da tashqi tirnoqni ham almashtirdik: ichida qo'shtirnoq kerak bo'lgani uchun JavaScript satri bittalik tirnoqda.

3-mashq (qiyin): Oshxona hisobi

Oshxonaga JSON matni keldi. hisobla(matn) funksiyasini yozing: u matnni o'qib, buyurtmaning umumiy summasini hisoblasin va javobni ham JSON matni qilib qaytarsin: {"stol":4,"jami":75000}. Summa — reduce bilan (reduce).

js
const kelgan =
  '{"stol":4,"taomlar":[' +
  '{"nom":"Osh","narx":35000,"soni":2},' +
  '{"nom":"Ko\'k choy","narx":5000,"soni":1}]}';
Yechim
js
const kelgan =
  '{"stol":4,"taomlar":[' +
  '{"nom":"Osh","narx":35000,"soni":2},' +
  '{"nom":"Ko\'k choy","narx":5000,"soni":1}]}';

function hisobla(matn) {
  const buyurtma = JSON.parse(matn);
  const jami = buyurtma.taomlar.reduce(
    (summa, taom) => summa + taom.narx * taom.soni,
    0,
  );
  return JSON.stringify({ stol: buyurtma.stol, jami });
}

const javob = hisobla(kelgan);
console.log(javob); // {"stol":4,"jami":75000}
console.log(typeof javob); // string

Funksiya "matn kiradi — matn chiqadi". Ichida esa oddiy obyekt va massiv bilan ishlaydi. Server kodlarining aksariyati aynan shunday: kirishda parse, oxirida stringify, o'rtada — oddiy JavaScript. { stol: buyurtma.stol, jami } dagi jami — shorthand xususiyat.

Bu misolda biz JSON matnini satrlarni qo'shib yozdik — faqat uzun qatorni bo'lish uchun, o'zimiz yozgan tayyor matn bo'lgani uchun. Yangi JSON yasashda doim stringify dan foydalaning.

4-mashq: Vazifalar qadami — JSON eksport

vazifalar ilovasiga yana bir yangi imkoniyat qo'shamiz — saralash va statistikadan keyin uchinchisi: eksport. Foydalanuvchi tugmani bosadi — vazifalar ro'yxati matn maydonida JSON bo'lib chiqadi. Uni nusxalab, xabarga yoki faylga saqlab qo'yish mumkin.

Bu — yangi imkoniyat, refaktoring emas. Shuning uchun branch prefiksi feature/: git switch -c feature/eksport.

Talablar:

  1. index.html da, #elon paragrafidan keyin: Eksport sarlavhasi (h2), id="eksport-tugma" tugma va id="eksport-matn" faqat o'qiladigan (readonly) textarea — yorlig'i bilan.
  2. vazifalar.js da toza funksiya eksportMatni(vazifalar) — JSON matnini qaytaradi.
  3. Tugma bosilganda matn maydonga yoziladi, fokus maydonga o'tadi va matn belgilanadi (select()). #elon da: "JSON tayyor. Nusxa olish uchun Ctrl+C bosing."
Yechim

index.html — <p id="elon" role="status"></p> dan keyin:

html
<h2>Eksport</h2>
<button type="button" id="eksport-tugma">JSON qilib chiqarish</button>
<label for="eksport-matn">Vazifalar JSON ko'rinishida</label>
<textarea id="eksport-matn" rows="6" readonly></textarea>

vazifalar.js — "2. Sahifa elementlari" bo'limiga ikki qator:

js
const eksportTugma = document.getElementById("eksport-tugma");
const eksportMatn = document.getElementById("eksport-matn");

"3. Hisoblovchi funksiyalar" bo'limiga:

js
function eksportMatni(vazifalar) {
  return JSON.stringify(vazifalar);
}

"7. Hodisalar" bo'limining oxiriga, render(); dan oldin:

js
eksportTugma.addEventListener("click", () => {
  eksportMatn.value = eksportMatni(holat.vazifalar);
  eksportMatn.focus();
  eksportMatn.select();
  elonQil("JSON tayyor. Nusxa olish uchun Ctrl+C bosing.");
});

Nega shunday:

  • eksportMatni — toza funksiya. U holat ni o'zi o'qimaydi, ro'yxatni parametr sifatida oladi. Uni Node'da brauzersiz sinash mumkin (pastda).
  • readonly — maydonni tahrirlab bo'lmaydi, lekin belgilash va nusxalash mumkin. Ekran o'quvchi uni oddiy matn maydoni deb o'qiydi: Malika NVDA bilan yorliqni eshitadi.
  • select() — butun matnni belgilaydi. Foydalanuvchiga qolgani bitta Ctrl+C.
  • Eksport — surat. Matn bosilgan paytdagi holatni ko'rsatadi. Keyin vazifani belgilasangiz, maydondagi matn o'zgarmaydi — qayta bosish kerak. Bu ataylab: eksport — "shu paytdagi nusxa".

Matnni qaytadan o'qib, asl ro'yxat bilan solishtiring — Node'da:

js
function eksportMatni(vazifalar) {
  return JSON.stringify(vazifalar);
}

const vazifalar = [
  { id: 1, matn: "Non olish", bajarildi: false },
  { id: 2, matn: 'Kitob: "O\'tkan kunlar"', bajarildi: true },
];

const matn = eksportMatni(vazifalar);
const qaytgan = JSON.parse(matn);

console.log(matn);
console.log(qaytgan[1].matn === vazifalar[1].matn); // true
console.log(qaytgan[1] === vazifalar[1]); // false

Konsolda:

text
[{"id":1,"matn":"Non olish","bajarildi":false},{"id":2,"matn":"Kitob: \"O'tkan kunlar\"","bajarildi":true}]
true
false

Qo'shtirnoqli matn ham to'g'ri ekranlandi va to'g'ri qaytdi. Qaytgan obyekt — yangi: ichi bir xil, havolasi boshqa.

Brauzerda tekshiring:

  • «JSON qilib chiqarish» ni bosing — maydonda uch vazifa, matn to'liq belgilangan, fokus maydonda.
  • "Non olish" ni belgilang — "1 ta vazifa qoldi, 2 ta bajarildi", maydondagi matn esa o'zgarmadi. Tugmani yana bosing — endi "bajarildi":true.
  • Qo'shtirnoqli vazifa qo'shing (Kitob "Ufq") va eksport qiling — matnda \"Ufq\".
  • Tab bilan tugmaga boring, Enter — fokus maydonga o'tadi. Filtrlar, tahrirlash, o'chirish — avvalgidek.

Commit va merge:

bash
git add index.html assets/js/vazifalar.js
git commit -m "Vazifalar: ro'yxatni JSON qilib eksport qil"
git switch main
git merge feature/eksport
git push

Branch'ni o'chirmang — keyingi darsda eksport formatini yaxshilaymiz. Teskari yo'l — matndan vazifalarni import qilish — buzilgan JSON'ni ushlashni talab qiladi. Uni try / catch / finally darsida qo'shamiz. Ro'yxatni brauzerda saqlash esa — 11-qismda (localStorage), u ham ichida JSON ishlatadi.

9. Real ishda

  • API. Server va brauzer deyarli doim JSON bilan gaplashadi. Brauzer so'rovni stringify qilib yuboradi, javobni parse qilib o'qiydi. fetch dagi response.json() (11-qism) — ichida xuddi shu parse.
  • Saqlash. localStorage faqat satr saqlaydi. Obyektni saqlash — stringify, o'qish — parse (localStorage).
  • Konfiguratsiya. package.json, tsconfig.json, VS Code sozlamalari — JSON fayllar. Node ularni JSON.parse bilan o'qiydi.
  • Debug. console.log(JSON.stringify(obyekt)) — ichma-ich obyektni bitta qatorda to'liq ko'rishning tez yo'li. Node konsoli chuqur obyektni [Object] deb qisqartiradi, JSON esa yo'q.
  • Xavfsizlik. Eski kodda JSON'ni eval bilan o'qish uchraydi. Bu xavfli: matn ichidagi kod bajarilib ketadi. JSON.parse esa faqat ma'lumotni o'qiydi, hech qanday kodni bajarmaydi. Tashqaridan kelgan matn uchun faqat JSON.parse (eval va new Function).
  • Intervyu. "JSON va JS obyektining farqi?", "JSON.parse(JSON.stringify(x)) nimani yo'qotadi?" — ko'p beriladigan savollar.

Xulosa

  • JSON — matn (satr). U obyektga o'xshaydi, lekin qoidalari qattiqroq: kalit va satr faqat qo'shtirnoqda, oxirgi vergul va izoh yo'q.
  • JSON.stringify(qiymat) — qiymatni JSON matniga aylantiradi, maxsus belgilarni o'zi ekranlaydi.
  • JSON.parse(matn) — matndan yangi qiymat yasaydi. Turlar matndagidek: "35000" — satr, 35000 — son.
  • parse buzilgan matnda SyntaxError beradi; position — xato belgisining indeksi (0 dan).
  • "[object Object]" is not valid JSON — obyektni qayta parse qilyapsiz degani.
  • JSON'ni hech qachon satr qo'shib yasamang — stringify ishlating.

Keyingi dars: JSON chuqur: replacer, reviver va chegaralar — stringify va parse ni sozlaymiz: chiroyli chiqarish, kerakli maydonlarni tanlash, sanani tiklash va JSON'ga sig'maydigan turlar bilan ishlash.

Manbalar

  • MDN: "JSON", "JSON.stringify()", "JSON.parse()" — developer.mozilla.org
  • ECMA-404: The JSON Data Interchange Syntax — ecma-international.org
  • RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format — rfc-editor.org
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JSON JavaScript'da: JSON.stringify va JSON.parse asoslari — IlmHamroh