IlmHamroh
JavaScript Full-stack/8-qism. JavaScript asoslari57/61-dars20 daqiqa
Mundarija (37)

JavaScript obyekt destructuring: xususiyatlarni o'zgaruvchilarga ajratib olish

Qisqacha: Obyekt destructuring — obyektning kerakli xususiyatlarini bitta qatorda alohida o'zgaruvchilarga olish: const { ism, yosh } = talaba;. O'zgaruvchi nomi kalit nomi bilan bir xil bo'lishi kerak, tartib muhim emas. Kalit yo'q bo'lsa, o'zgaruvchi undefined bo'ladi. Nomini o'zgartirish (ism: mijozIsmi), default qiymat (tolov = "naqd") va "qolganini yig'ish" (...qolgan) ham shu sintaksisda yoziladi.

Bu darsda

  • const { a, b } = obyekt bilan xususiyatlarni o'zgaruvchilarga ajrata olasiz.
  • O'zgaruvchiga kalitdan boshqa nom bera olasiz va default qiymat qo'ya olasiz.
  • Ichma-ich obyektdan qiymat olasiz va "qolgan hammasi"ni ... bilan yig'asiz.
  • Funksiya qaytargan obyektni darhol ajratib olasiz.
  • Cannot destructure property xatosini tushunib, tuzata olasiz.

Oldin bilishingiz kerak: Obyekt: kalit-qiymat juftliklari, Shorthand, computed kalitlar va metodlar, Havola semantikasi, return va erta qaytish, ?? va ?..

1. Nega bu kerak?

Siz taksi ilovasi uchun kod yozyapsiz. Server sizga buyurtma haqida shunday obyekt beradi:

js
const buyurtma = {
  mijoz: "Malika",
  manzil: "Chilonzor 9",
  narx: 18000,
  tolov: "Click",
};

console.log(`Mijoz: ${buyurtma.mijoz}`);
console.log(`Manzil: ${buyurtma.manzil}`);
console.log(`Narx: ${buyurtma.narx} so'm`);
console.log(`To'lov: ${buyurtma.tolov}`);

Konsolda:

text
Mijoz: Malika
Manzil: Chilonzor 9
Narx: 18000 so'm
To'lov: Click

Kod ishlaydi. Lekin buyurtma. so'zi to'rt marta takrorlandi. Real ilovada bitta funksiya ichida o'nlab joyda buyurtma.narx, buyurtma.mijoz deb yozasiz. Kod uzun va o'qish qiyin bo'ladi.

Ko'pincha shunday qilishadi: avval kerakli xususiyatlarni alohida o'zgaruvchilarga olib qo'yishadi.

js
const mijoz = buyurtma.mijoz;
const manzil = buyurtma.manzil;
const narx = buyurtma.narx;

Bu yaxshiroq, lekin endi har bir nom ikki marta yozilyapti: mijoz = buyurtma.mijoz. JavaScript'da buning qisqa yo'li bor — destructuring.

Bu so'zni massiv bo'ylab yurish va obyekt bo'ylab yurish darslarida for (const [i, x] of ...) ko'rinishida uchratgansiz. U massiv destructuring edi — uni keyingi darsda to'liq ko'ramiz. Bugun obyekt destructuring bilan boshlaymiz.

2. Birinchi destructuring

2.1 Sintaksis

Ajratib olish (destructuring) — obyekt yoki massivning ichidagi qiymatlarni bitta qatorda alohida o'zgaruvchilarga olish. Dasturchilar orasida inglizcha nomi ishlatiladi, biz ham "destructuring" deymiz.

Hayotdan o'xshatish: bozordan to'la xalta bilan qaytdingiz. Xaltani ag'darib hammasini to'kmaysiz. "Non, sut, pomidor" deb aytasiz va aynan shularni nomi bilan olasiz. Xalta esa joyida qoladi.

js
const buyurtma = {
  mijoz: "Malika",
  manzil: "Chilonzor 9",
  narx: 18000,
  tolov: "Click",
};

const { mijoz, manzil, narx } = buyurtma;

console.log(mijoz); // Malika
console.log(manzil); // Chilonzor 9
console.log(narx); // 18000

Keling, const { mijoz, manzil, narx } = buyurtma; qatorini bo'laklab o'qiymiz:

  • const — odatdagidek, yangi o'zgaruvchi e'lon qilyapmiz. Bu safar bittasini emas, uchtasini birdaniga.
  • { mijoz, manzil, narx } — qolip. Jingalak qavs = belgisining chap tomonida turibdi. Bu yerda u obyekt yasamaydi, balki "obyektdan shu nomli kalitlarni ol" degan buyruq beradi.
  • = buyurtma — qaysi obyektdan olish kerakligi.

Natijada uchta oddiy o'zgaruvchi paydo bo'ldi. Bu qator quyidagi uch qatorning aynan o'zi:

js
const mijoz = buyurtma.mijoz;
const manzil = buyurtma.manzil;
const narx = buyurtma.narx;

tolov kalitini qolipga yozmadik — demak, u olinmadi. Obyektning hamma kalitini olish shart emas, faqat keraklisini olasiz.

2.2 Chap tomon — "teskari" obyekt

Shorthand darsida obyektni shunday yasagan edik:

js
const mijoz = "Malika";
const narx = 18000;

const buyurtma = { mijoz, narx }; // obyekt YASASH
console.log(buyurtma); // { mijoz: 'Malika', narx: 18000 }

Destructuring — buning teskarisi:

js
const buyurtma = { mijoz: "Malika", narx: 18000 };

const { mijoz, narx } = buyurtma; // obyektni AJRATISH
console.log(mijoz, narx); // Malika 18000

Ko'rinishi deyarli bir xil. Farq — { } qaysi tomonda turganida:

Qayerda Nima qiladi Misol
= ning o'ng tomonida Obyekt yasaydi const b = { mijoz, narx };
= ning chap tomonida Obyektni ajratadi const { mijoz, narx } = b;

Boshida bu chalkash tuyulishi tabiiy. Qoida bitta: const dan keyin darhol { kelsa — bu destructuring.

2.3 Nom muhim, tartib emas

Obyekt destructuring kalitni nomi bo'yicha qidiradi. Qolipda nomlarni qaysi tartibda yozishingiz ahamiyatsiz:

js
const talaba = { ism: "Jasur", yosh: 20, shahar: "Samarqand" };

const { shahar, ism } = talaba;
console.log(ism); // Jasur
console.log(shahar); // Samarqand

Obyektda ism birinchi, shahar uchinchi turibdi. Qolipda esa teskari. Baribir har bir o'zgaruvchi o'z kalitini topdi.

Shu sababli o'zgaruvchi nomi kalit nomi bilan harfma-harf bir xil bo'lishi shart. Aks holda nima bo'lishini keyingi bo'limda ko'ramiz.

2.4 Kalit yo'q bo'lsa — undefined

Obyekt darsida ko'rgandingiz: yo'q xususiyatni o'qisangiz, xato emas, undefined keladi. Destructuring ham xuddi shunday:

js
const talaba = { ism: "Jasur", yosh: 20 };

const { ism, telefon } = talaba;
console.log(ism); // Jasur
console.log(telefon); // undefined

talaba da telefon kaliti yo'q. JavaScript xato bermadi — shunchaki telefon o'zgaruvchisiga undefined yozdi.

Bu qulay, lekin xavfli ham. Bitta harfni adashtirsangiz, JavaScript sizni ogohlantirmaydi:

js
const talaba = { ism: "Jasur", yosh: 20 };

const { Ism } = talaba; // katta "I" bilan
console.log(Ism); // undefined

Konsolda undefined ko'rsangiz, birinchi navbatda qolipdagi nom kalit nomi bilan bir xilmi — shuni tekshiring. Katta-kichik harf ham farq qiladi.

2.5 Asl obyekt o'zgarmaydi

Destructuring obyektdan qiymatlarni ko'chirib oladi. Obyektning o'zi joyida qoladi — xuddi xaltadan non olganingizdek, xalta yo'qolmaydi.

js
const mahsulot = { nomi: "Olma", narx: 12000 };

let { narx } = mahsulot;
narx = narx - 2000; // chegirma

console.log(narx); // 10000
console.log(mahsulot.narx); // 12000

narx o'zgaruvchisini o'zgartirdik, lekin mahsulot.narx avvalgidek 12000. Chunki son — primitiv qiymat, u nusxalanadi.

E'tibor bering: bu yerda const emas, let yozdik. Destructuring bilan yaratilgan o'zgaruvchilar oddiy o'zgaruvchilar kabi: const bo'lsa — qayta tayinlab bo'lmaydi, let bo'lsa — bo'ladi.

Tekshirib ko'ring: Konsolda nima chiqadi?

js
const kitob = { nomi: "O'tkan kunlar", muallif: "Abdulla Qodiriy" };
const { muallif, yil } = kitob;
console.log(muallif, yil);
Javob

Abdulla Qodiriy undefined. muallif kaliti obyektda bor — uning qiymati olindi. yil kaliti esa yo'q, shuning uchun yil o'zgaruvchisi undefined bo'ldi. Xato chiqmaydi.

Tekshirib ko'ring: const { narx, nomi } = mahsulot; va const { nomi, narx } = mahsulot; — natijada farq bormi?

Javob

Farq yo'q. Obyekt destructuring kalitni nomi bo'yicha topadi, qolipdagi tartib ahamiyatsiz. Ikkala holatda ham nomi va narx bir xil qiymat oladi.

3. O'zgaruvchiga boshqa nom berish

3.1 Muammo: nomlar to'qnashdi

Tasavvur qiling, ikkita obyektdan ma'lumot olyapsiz. Ikkalasida ham ism kaliti bor:

js
const haydovchi = { ism: "Rustam", mashina: "Cobalt" };
const yolovchi = { ism: "Malika", manzil: "Yunusobod" };

const { ism } = haydovchi;
const { ism } = yolovchi;
text
SyntaxError: Identifier 'ism' has already been declared

Tarjimasi: "ism nomi allaqachon e'lon qilingan". Bitta joyda ikkita ism o'zgaruvchisi bo'la olmaydi. Demak, kamida bittasiga boshqa nom kerak.

3.2 Yechim: kalit: yangiNom

js
const haydovchi = { ism: "Rustam", mashina: "Cobalt" };
const yolovchi = { ism: "Malika", manzil: "Yunusobod" };

const { ism: haydovchiIsmi } = haydovchi;
const { ism: yolovchiIsmi } = yolovchi;

console.log(haydovchiIsmi); // Rustam
console.log(yolovchiIsmi); // Malika

{ ism: haydovchiIsmi } qolipi shunday o'qiladi: "ism kalitining qiymatini ol va uni haydovchiIsmi nomli o'zgaruvchiga yoz".

Diqqat: Bu yerda ikki nuqta ma'nosi obyekt yasashdagidan boshqacha. Obyekt yasashda { ism: "Ali" } — chapda kalit, o'ngda qiymat. Destructuringda { ism: haydovchiIsmi } — chapda kalit, o'ngda yangi o'zgaruvchi nomi. Eslab qolish uchun: kalit har doim chapda. O'ng tomon — "qayerga qo'yish".

Qayta nomlangandan keyin eski nom bilan o'zgaruvchi yaratilmaydi:

js
const haydovchi = { ism: "Rustam", mashina: "Cobalt" };
const { ism: haydovchiIsmi } = haydovchi;

console.log(ism);
text
ReferenceError: ism is not defined

"ism aniqlanmagan". Chunki ism bu yerda faqat qaysi kalitdan olish kerakligini bildirdi. O'zgaruvchi esa haydovchiIsmi nomi bilan yaratildi.

3.3 Qachon yana qayta nomlash kerak?

Nomlar to'qnashuvidan tashqari yana ikki holat bor.

Birinchisi: kalit nomi tushunarsiz bo'lsa. Serverdan ko'pincha qisqa nomlar keladi: { s: 25000 }. Uni { s: summa } deb ochib, kodda aniq nom bilan ishlaysiz.

Ikkinchisi: kalit nomi o'zgaruvchi nomi bo'la olmasa. Masalan, ichida tire bor kalit — "tolov-turi". Bunday nomli o'zgaruvchi yaratib bo'lmaydi, shuning uchun qayta nomlash majburiy:

js
const chek = { "tolov-turi": "Payme", summa: 45000 };

const { "tolov-turi": tolovTuri, summa } = chek;
console.log(tolovTuri); // Payme
console.log(summa); // 45000

Kalit qo'shtirnoq ichida yozildi — xuddi obyekt yaratishdagidek. summa esa oddiy usulda olindi: bitta qolipda ikkala usulni aralashtirish mumkin.

Maslahat: Kalit nomi o'zgaruvchida saqlangan bo'lsa, computed kalitlar dagi kvadrat qavs bu yerda ham ishlaydi: const { [kalit]: qiymat } = obyekt;. Bunda qayta nomlash majburiy — o'zgaruvchiga nom berish kerak.

Tekshirib ko'ring: const { narx: summa } = mahsulot; qatoridan keyin qaysi o'zgaruvchi mavjud: narxmi yoki summami?

Javob

Faqat summa. narx — obyektdagi kalit nomi, u faqat "qayerdan olish"ni ko'rsatadi. Yaratilgan o'zgaruvchi — ikki nuqtadan keyingi nom, ya'ni summa.

4. Default qiymat

4.1 Kalit yo'q bo'lsa — zaxira qiymat

Ba'zi buyurtmalarda tolov kaliti bo'lmaydi. Bunday holatda "naqd" deb hisoblamoqchimiz:

js
const buyurtma = { mijoz: "Jasur", narx: 15000 };

const { mijoz, tolov = "naqd" } = buyurtma;
console.log(mijoz); // Jasur
console.log(tolov); // naqd

tolov = "naqd" — default qiymat: kalit yo'q bo'lsa, shu qiymat olinadi. Xuddi parametrlardagi default kabi yoziladi va xuddi shunday ishlaydi.

Kalit bor bo'lsa — default e'tiborga olinmaydi:

js
const buyurtma = { mijoz: "Jasur", tolov: "Click" };

const { tolov = "naqd" } = buyurtma;
console.log(tolov); // Click

4.2 Faqat undefined da ishlaydi

Default qiymat faqat qiymat undefined bo'lganda ishlaydi. null, 0 yoki "" bo'lsa — ishlamaydi:

js
const sozlama = { til: null, ovoz: 0, mavzu: undefined };

const { til = "uz", ovoz = 50, mavzu = "yorug'" } = sozlama;
console.log(til); // null
console.log(ovoz); // 0
console.log(mavzu); // yorug'

til ning qiymati null — bu "qiymat ataylab bo'sh" degani, JavaScript uni qiymat deb hisobladi. ovoz — 0, bu ham haqiqiy qiymat. Faqat mavzu undefined edi, shuning uchun default ishladi.

Bu ?? operatoriga o'xshaydi, lekin bir farqi bor: ?? null da ham zaxira beradi, destructuring defaulti esa faqat undefined da. null da ham zaxira kerak bo'lsa — alohida ?? yozing:

js
const sozlama = { til: null };

const { til } = sozlama;
const tanlanganTil = til ?? "uz";
console.log(tanlanganTil); // uz

4.3 Qayta nomlash va default birga

Ikkalasini bitta joyda yozsa bo'ladi. Tartib: avval kalit, keyin ikki nuqta va yangi nom, oxirida = va default:

js
const buyurtma = { mijoz: "Jasur" };

const { tolov: tolovUsuli = "naqd" } = buyurtma;
console.log(tolovUsuli); // naqd

O'qilishi: "tolov kalitini ol, tolovUsuli ga yoz, agar yo'q bo'lsa — "naqd"".

Maslahat: Default qiymat sifatida funksiya chaqiruvini ham yozish mumkin: { vaqt = hozirgiVaqt() }. U faqat kalit yo'q bo'lganda chaqiriladi. Kalit bor bo'lsa, funksiya umuman ishga tushmaydi.

Tekshirib ko'ring: const { chegirma = 10 } = { chegirma: 0 }; dan keyin chegirma nimaga teng?

Javob

0. Kalit bor va uning qiymati 0 — bu undefined emas. Default faqat undefined da ishlaydi, shuning uchun 10 olinmadi.

5. Ichma-ich obyektlar

5.1 Ichkaridagi qiymatni olish

Real ma'lumot ko'pincha qatlam-qatlam bo'ladi. Masalan, foydalanuvchining manzili alohida obyekt ichida:

js
const foydalanuvchi = {
  ism: "Dilnoza",
  manzil: {
    shahar: "Farg'ona",
    kocha: "Mustaqillik 12",
  },
};

const { ism, manzil: { shahar } } = foydalanuvchi;
console.log(ism); // Dilnoza
console.log(shahar); // Farg'ona

manzil: { shahar } qismi shunday o'qiladi: "manzil kalitiga kir, uning ichidan shahar ni ol".

Bu qayta nomlash sintaksisiga o'xshaydi. Farqi — ikki nuqtadan keyin nom emas, yana bitta qolip ({ shahar }) turibdi. JavaScript buni "ichkariga kir" deb tushunadi.

5.2 Oraliq kalit o'zgaruvchi bo'lmaydi

Tuzoq shunda: bu qatordan keyin manzil degan o'zgaruvchi yaratilmaydi. U faqat yo'l ko'rsatdi.

js
const foydalanuvchi = {
  ism: "Dilnoza",
  manzil: { shahar: "Farg'ona", kocha: "Mustaqillik 12" },
};

const { manzil: { shahar } } = foydalanuvchi;
console.log(manzil);
text
ReferenceError: manzil is not defined

manzil ham, shahar ham kerak bo'lsa — ikkalasini alohida yozasiz:

js
const foydalanuvchi = {
  ism: "Dilnoza",
  manzil: { shahar: "Farg'ona", kocha: "Mustaqillik 12" },
};

const { manzil, manzil: { shahar } } = foydalanuvchi;
console.log(shahar); // Farg'ona
console.log(manzil.kocha); // Mustaqillik 12

Bitta kalitni qolipda ikki marta ishlatish mumkin — bu xato emas.

5.3 Ichki obyekt yo'q bo'lsa

Agar foydalanuvchida manzil umuman bo'lmasa-chi?

js
const foydalanuvchi = { ism: "Sardor" };

const { manzil: { shahar } } = foydalanuvchi;
text
TypeError: Cannot read properties of undefined (reading 'shahar')

Tarjimasi: "undefined ning xususiyatlarini o'qib bo'lmaydi (shahar ni o'qiyotganda)". JavaScript manzil ni oldi — u undefined chiqdi. Keyin undefined ichidan shahar ni qidirmoqchi bo'ldi va yiqildi.

Yechim — ichki qolipga default sifatida bo'sh obyekt berish:

js
const foydalanuvchi = { ism: "Sardor" };

const { manzil: { shahar = "noma'lum" } = {} } = foydalanuvchi;
console.log(shahar); // noma'lum

= {} shuni aytadi: "manzil yo'q bo'lsa, o'rniga bo'sh obyekt ol". Bo'sh obyektda shahar yo'q — demak, shahar ga uning o'z defaulti "noma'lum" yoziladi.

Diqqat: Ichma-ich destructuringni 2 qavatdan chuqur qilmang. { a: { b: { c: { d } } } } kabi qatorni o'qish juda qiyin. Chuqur ma'lumotda ba'zan foydalanuvchi.manzil?.shahar deb ?. bilan o'qish tushunarliroq.

5.4 Ichki obyekt — havola

Havola semantikasi darsini eslang: obyekt o'zgaruvchida nusxa sifatida emas, havola sifatida saqlanadi. Destructuring ham bu qoidani o'zgartirmaydi:

js
const foydalanuvchi = {
  ism: "Dilnoza",
  manzil: { shahar: "Farg'ona" },
};

const { manzil } = foydalanuvchi;
manzil.shahar = "Qo'qon";

console.log(foydalanuvchi.manzil.shahar); // Qo'qon

manzil — yangi obyekt emas, o'sha eski obyektga ikkinchi havola. Uni o'zgartirsak, foydalanuvchi ichidagi manzil ham o'zgaradi. Son va satr kabi primitivlar nusxalanadi (chegirmali narx misolini eslang), obyekt va massivlar esa yo'q.

Tekshirib ko'ring: const { ota: { ism } } = oila; qatoridan keyin qaysi o'zgaruvchilar mavjud?

Javob

Faqat ism. ota — "ichkariga kirish" uchun yo'l ko'rsatkich, u o'zgaruvchi bo'lmaydi. ota ham kerak bo'lsa, qolipga alohida yozish kerak: const { ota, ota: { ism } } = oila;.

6. Qolganini yig'ish: ...qolgan

6.1 Bittasini olib, qolganini alohida saqlash

Ba'zan bitta-ikkita kalitni ajratib, qolgan hammasini bitta yangi obyektga yig'ish kerak bo'ladi. Masalan, to'lov ma'lumotini konsolga chiqarishdan oldin karta raqamini olib tashlaymiz — u logga tushmasligi kerak:

js
const tolov = {
  kartaRaqami: "8600 1234 5678 9012",
  summa: 45000,
  dokon: "Korzinka",
};

const { kartaRaqami, ...xavfsiz } = tolov;
console.log(xavfsiz); // { summa: 45000, dokon: 'Korzinka' }

...xavfsiz — rest ("qolgani"). U qolipda nomi aytilmagan barcha kalitlarni yangi obyektga yig'adi. kartaRaqami alohida o'zgaruvchiga ketdi, xavfsiz ichida esa u yo'q.

Asl tolov obyekti o'zgarmadi — unda uchala kalit ham joyida. xavfsiz — butunlay yangi obyekt.

Maslahat: Bu usul delete tolov.kartaRaqami dan yaxshiroq. delete asl obyektni buzadi — boshqa joyda karta raqami kerak bo'lsa, u yo'qolgan bo'ladi. Rest esa aslini tegmasdan, yangi "tozalangan" obyekt beradi.

6.2 Rest — har doim oxirida

... bilan yozilgan qism qolipning eng oxirida turishi shart. Mantiqan ham shunday: "qolgani" faqat boshqalar olingandan keyin ma'lum bo'ladi.

js
const tolov = { kartaRaqami: "8600 1234", summa: 45000 };

const { ...qolgan, summa } = tolov;
text
SyntaxError: Rest element must be last element

Tarjimasi: "Rest element oxirgi element bo'lishi shart". Bu SyntaxError — kod umuman ishga tushmaydi. Qolipda faqat bitta ... bo'ladi va u oxirida turadi.

... belgisi JavaScript'da yana bir nechta joyda uchraydi. Uni spread va rest darsida to'liq o'rganamiz.

Tekshirib ko'ring: const { a, ...qolgan } = { a: 1 }; dan keyin qolgan nimaga teng?

Javob

{} — bo'sh obyekt. a dan boshqa kalit yo'q, yig'adigan narsa qolmadi. Lekin qolgan baribir obyekt bo'ladi, undefined emas.

7. Funksiya qaytargan obyektni ajratish

return darsida aytgandik: funksiya bir nechta qiymat qaytarishi kerak bo'lsa, ularni bitta obyektga solib qaytaradi. Destructuring bilan bunday natijani ochish juda qulay:

js
function chekHisobla(narx, soni) {
  const jami = narx * soni;
  const qqs = jami * 0.12;
  return { jami, qqs };
}

const { jami, qqs } = chekHisobla(15000, 3);
console.log(jami); // 45000
console.log(qqs); // 5400

chekHisobla(15000, 3) avval ishlaydi va { jami: 45000, qqs: 5400 } obyektini qaytaradi. Keyin destructuring uni ikki o'zgaruvchiga ajratadi. Oraliq o'zgaruvchi (const natija = ...) kerak bo'lmadi.

Bu usulning bir afzalligi bor: sizga faqat bittasi kerak bo'lsa — faqat uni olasiz:

js
function chekHisobla(narx, soni) {
  const jami = narx * soni;
  return { jami, qqs: jami * 0.12 };
}

const { qqs } = chekHisobla(20000, 1);
console.log(qqs); // 2400

Funksiya ichida return { jami, qqs } — shorthand bilan obyekt yasash. Tashqarida const { jami, qqs } = ... — o'sha obyektni ajratish. Ikki tomon bir-biriga ko'zgudek mos.

Maslahat: Destructuringni funksiya parametrida ham yozish mumkin: function f({ ism, yosh }) { ... }. Bu real kodda juda ko'p uchraydi. Uni alohida — Parametrda destructuring darsida o'rganamiz.

8. Oldin e'lon qilingan o'zgaruvchiga destructuring

Hozirgacha doim const yoki let bilan yangi o'zgaruvchi yaratdik. Agar o'zgaruvchi oldinroq e'lon qilingan bo'lsa-chi? Sezgi bilan shunday yozasiz:

js
let ism;
let yosh;

{ ism, yosh } = { ism: "Aziz", yosh: 22 };
text
SyntaxError: Unexpected token '='

Tarjimasi: "Kutilmagan belgi: =". Nega? Qator { bilan boshlandi. JavaScript buni obyekt emas, if dagi kabi kod bloki deb o'qidi. Blokdan keyin = kelishi mumkin emas.

Yechim — butun ifodani oddiy qavsga olish:

js
let ism;
let yosh;

({ ism, yosh } = { ism: "Aziz", yosh: 22 });
console.log(ism, yosh); // Aziz 22

Qavs JavaScript'ga "bu blok emas, ifoda" deb bildiradi. Bunday yozuv kamdan-kam kerak bo'ladi. Ko'pincha const { ... } = ... ni ishlatasiz.

Diqqat: Qavs bilan boshlanadigan qatordan oldingi qatorda nuqta-vergul bo'lishi shart. Aks holda ASI tuzog'i ishlaydi: JavaScript ikki qatorni bitta deb o'qiydi. Kursda doim ; qo'yamiz — shu tuzoqdan saqlaydi.

9. Ko'p uchraydigan xatolar

9.1 null yoki undefined ni ajratish

Eng ko'p uchraydigan xato. Funksiya hech narsa qaytarmadi yoki server ma'lumot bermadi — siz esa uni ajratmoqchisiz:

js
const javob = undefined;

const { ism } = javob;
text
TypeError: Cannot destructure property 'ism' of 'javob' as it is undefined.

Tarjimasi: "javob dan ism xususiyatini ajratib bo'lmaydi, chunki u undefined". Xabar sizga uch narsani aytyapti: qaysi kalit (ism), qaysi o'zgaruvchi (javob) va nima ekani (undefined). null bo'lsa, oxirida as it is null deyiladi.

Funksiya natijasini ajratayotganda xabarda o'zgaruvchi nomi o'rniga funksiya ko'rinadi:

js
function foydalanuvchiniTop() {
  // hech narsa qaytarmadi
}

const { ism } = foydalanuvchiniTop();
text
TypeError: Cannot destructure property 'ism' of 'foydalanuvchiniTop(...)' as it is undefined.

foydalanuvchiniTop(...) — "shu funksiya qaytargan natija". returnsiz funksiya undefined qaytaradi, undefined ni esa ajratib bo'lmaydi.

Tuzatish: qiymat yo'q bo'lishi mumkin bo'lsa, ?? {} bilan bo'sh obyektga almashtiring:

js
const javob = undefined;

const { ism = "Mehmon" } = javob ?? {};
console.log(ism); // Mehmon

javob ?? {} — javob null yoki undefined bo'lsa, o'rniga {} olinadi. Bo'sh obyektni ajratish mumkin — xato yo'q.

Maslahat: Faqat null va undefined ni ajratib bo'lmaydi. Son yoki satrni ajratish xato bermaydi: const { length } = "salom"; — length 5 ga teng bo'ladi. JavaScript satrni vaqtincha obyektga o'rab, uning xususiyatini oladi.

9.2 Ichki obyekt yo'q

TypeError: Cannot read properties of undefined (reading 'shahar') — buni ichma-ich obyektlar mavzusida ko'rdik. Oraliq kalit (manzil) yo'q bo'lsa chiqadi. Tuzatish — ichki qolipga = {} default.

9.3 Qayta nomlashda yo'nalishni adashtirish

js
const mahsulot = { narx: 12000 };

const { summa: narx } = mahsulot; // ❌ teskari yozildi
console.log(narx); // undefined

Bu qator "summa kalitini ol va narx ga yoz" degani. Obyektda summa yo'q — shuning uchun undefined. To'g'risi: const { narx: summa } = mahsulot;. Esingizda bo'lsin: kalit — chapda, yangi nom — o'ngda.

9.4 Qavssiz { ... } =

SyntaxError: Unexpected token '=' — oldin e'lon qilingan o'zgaruvchiga qavssiz destructuring yozilganda chiqadi. Tuzatish — butun ifodani qavsga olish: ({ ... } = obyekt);.

10. Mashqlar

1-mashq (oson): Telegram profili

Quyidagi obyektdan ism, username va obunachilar ni destructuring bilan oling va konsolga chiqaring.

js
const profil = {
  ism: "Sardor",
  username: "@sardor_dev",
  obunachilar: 1520,
  til: "uz",
};

Kutilgan natija: Sardor (@sardor_dev) — 1520 obunachi. Satrni template literal bilan yig'ing: `${ism} (...)`.

Yechim
js
const profil = {
  ism: "Sardor",
  username: "@sardor_dev",
  obunachilar: 1520,
  til: "uz",
};

const { ism, username, obunachilar } = profil;
console.log(`${ism} (${username}) — ${obunachilar} obunachi`);
// Sardor (@sardor_dev) — 1520 obunachi

til kerak emas edi — uni qolipga yozmadik. Kalitlar qolipda qaysi tartibda yozilishi ahamiyatsiz.

2-mashq (o'rta): Yetkazib berish

Quyidagi buyurtmadan:

  • mijoz ni ism nomi bilan;
  • manzil ichidagi tuman ni;
  • yetkazish ni oling. U yo'q bo'lsa, 10000 bo'lsin.

Keyin Malika, Yakkasaroy, yetkazish: 10000 so'm qatorini chiqaring.

js
const buyurtma = {
  mijoz: "Malika",
  manzil: { shahar: "Toshkent", tuman: "Yakkasaroy" },
  narx: 56000,
};

Ishora: qayta nomlash — kalit: yangiNom, ichkariga kirish — kalit: { ichki }, default — kalit = qiymat.

Yechim
js
const buyurtma = {
  mijoz: "Malika",
  manzil: { shahar: "Toshkent", tuman: "Yakkasaroy" },
  narx: 56000,
};

const {
  mijoz: ism,
  manzil: { tuman },
  yetkazish = 10000,
} = buyurtma;

console.log(`${ism}, ${tuman}, yetkazish: ${yetkazish} so'm`);
// Malika, Yakkasaroy, yetkazish: 10000 so'm

Qolip uzun bo'lsa, uni obyekt kabi bir necha qatorga yozish mumkin — o'qish osonlashadi. buyurtma da yetkazish kaliti yo'q, shuning uchun default 10000 olindi.

3-mashq (qiyin): Xavfsiz profil

ochiqProfil funksiyasini yozing. U foydalanuvchi obyektini oladi va:

  1. telefon va pasport kalitlarini olib tashlab, qolgan hammasini yangi obyekt sifatida qaytaradi (rest bilan).
  2. Agar funksiyaga undefined berilsa, xato chiqmasin — bo'sh obyekt qaytsin (?? {} bilan).

Asl obyekt o'zgarmasligini ham tekshiring.

js
const talaba = {
  ism: "Jasur",
  telefon: "+998 90 123 45 67",
  pasport: "AB1234567",
  kurs: "JavaScript",
};
Yechim
js
function ochiqProfil(foydalanuvchi) {
  const { telefon, pasport, ...ochiq } = foydalanuvchi ?? {};
  return ochiq;
}

const talaba = {
  ism: "Jasur",
  telefon: "+998 90 123 45 67",
  pasport: "AB1234567",
  kurs: "JavaScript",
};

console.log(ochiqProfil(talaba));
console.log(ochiqProfil(undefined));
console.log(talaba.telefon);

Konsolda:

text
{ ism: 'Jasur', kurs: 'JavaScript' }
{}
+998 90 123 45 67

telefon va pasport o'zgaruvchilarga ajratildi, lekin ishlatilmadi — ularni faqat ochiq ichiga tushmasligi uchun oldik. undefined berilganda ?? {} bo'sh obyekt beradi, uni ajratish esa xavfsiz. Oxirgi qator asl talaba o'zgarmaganini ko'rsatadi.

11. Real ishda

Destructuring — zamonaviy JavaScript'da eng ko'p ishlatiladigan sintaksislardan biri. Deyarli har bir faylda uchratasiz:

  • Server javoblari. Ilova serverdan katta obyekt oladi va darhol keraklisini ajratadi: const { ism, balans } = javob;.
  • Maxfiy ma'lumotni tozalash. Foydalanuvchini logga yozish yoki boshqa xizmatga yuborishdan oldin const { parol, ...ochiq } = user; bilan maxfiy maydon olib tashlanadi. Bu xavfsizlik bo'yicha odatiy amaliyot.
  • React (sayt yasash uchun mashhur kutubxona, kursda alohida qism bor): komponentga keladigan ma'lumotlar deyarli har doim destructuring bilan ochiladi. Hozir bilish shart emas — faqat sintaksis tanish bo'lsin.
  • Import. Keyinroq modullarda import { readFile } from "node:fs" kabi qatorlarni ko'rasiz. Ko'rinishi o'xshash, lekin bu boshqa mexanizm — modullar qismida tushuntiramiz.

Intervyuda ko'pincha shunday so'rashadi: "const { a: b = 5 } = obj qatori nima qiladi?". Javob: obj.a ni b o'zgaruvchisiga oladi, obj.a undefined bo'lsa — 5.

Xulosa

  • const { a, b } = obyekt; — obyektdan kalitlarni shu nomli o'zgaruvchilarga ajratadi. Tartib emas, nom muhim.
  • Yo'q kalit — undefined. Nomdagi bitta harf xatosi ham undefined beradi.
  • { kalit: yangiNom } — qayta nomlash, { kalit = default } — zaxira qiymat (faqat undefined da ishlaydi).
  • { tashqi: { ichki } } — ichma-ich ajratish. tashqi o'zgaruvchi bo'lmaydi. Yo'q bo'lishi mumkin bo'lsa — = {}.
  • { a, ...qolgan } — qolgan kalitlarni yangi obyektga yig'adi. Rest har doim oxirida.
  • null/undefined ni ajratib bo'lmaydi — ?? {} bilan himoyalaning.

Keyingi dars: Massiv destructuring — xuddi shu g'oyani massivlarga qo'llaymiz: bu yerda nom emas, o'rin (pozitsiya) muhim bo'ladi.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript obyekt destructuring: xususiyatlarni o'zgaruvchilarga ajratib olish — IlmHamroh