Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. ?? — nullish coalescing
- 2.1 Faqat null va undefined uchun zaxira
- 2.2 ?? va ||: yonma-yon
- 2.3 Qachon ??, qachon ||?
- 2.4 Zanjir va qisqa tutashuv
- 3. ?. — optional chaining
- 3.1 Obyektni eslaymiz
- 3.2 Muammo: "yo'q"ning ichiga qarash
- 3.3 Yechim: ?.
- 3.4 ?. ning boshqa shakllari
- 4. Mantiqiy tayinlash: ||=, &&=, ??=
- 4.1 += ni eslang
- 4.2 ??= — standart qiymat qo'yish
- 4.3 &&= — faqat qiymat bo'lsa yangilash
- 4.4 Nozik detal: keraksiz tayinlash bo'lmaydi
- 5. Ko'p uchraydigan xatolar
- 5.1 ?? ni || yoki && bilan qavssiz aralashtirish
- 5.2 ?. ni tayinlashning chap tomoniga yozish
- 5.3 E'lon qilinmagan o'zgaruvchi bilan ?.
- 5.4 ?? o'rniga || yozib, 0 ni yo'qotish
- 6. Mashqlar
- 1-mashq (oson): ?? yoki ||?
- 2-mashq (o'rta): Ilova sozlamalari
- 3-mashq (qiyin): Yetkazib berish narxi
- 7. Real ishda
- Xulosa
JavaScript ?? va ?. operatorlari: nullish coalescing, optional chaining va mantiqiy tayinlash
Qisqacha: Nullish coalescing operatori
??chap tomon faqatnullyokiundefinedbo'lsa zaxira qiymatni oladi. U||dan farqli ravishda0va""ni saqlab qoladi. Optional chaining?.esa qiymatnullyokiundefinedbo'lsa, xato bermayundefinedqaytaradi. Mantiqiy tayinlash (??=,||=,&&=) — shu operatorlarning tayinlash bilan birlashgan qisqa shakli.
Bu darsda
??bilan0va""ni yo'qotmaydigan default qiymat bera olasiz.??va||farqini tushuntira olasiz va qachon qaysi biri kerakligini bilasiz.?.bilan "yo'q" qiymatdan xatosiz ma'lumot o'qiy olasiz.??=,||=va&&=mantiqiy tayinlash operatorlarini ishlata olasiz.- Bu operatorlar bilan bog'liq uchta sintaksis xatosini taniysiz.
Oldin bilishingiz kerak: Mantiqiy operatorlar va qisqa tutashuv, undefined va null, Arifmetik va tayinlash operatorlari.
1. Nega bu kerak?
O'tgan darsdagi choyxona misolini eslang. Mijoz shakarsiz choy xohladi va 0 ni tanladi. || esa baribir 2 qoshiq soldi:
const tanlanganShakar = 0;
console.log(tanlanganShakar || 2); // 2Sababi: || hamma falsy qiymatni "yo'q" deb hisoblaydi. 0 esa falsy. Lekin bu yerda 0 — "yo'q" emas, mijozning aniq tanlovi.
Bizga boshqa savol beradigan operator kerak. "Qiymat falsymi?" emas, "qiymat umuman bormi?" deb so'raydigan. Ya'ni faqat null yoki undefined bo'lganda zaxiraga o'tadigan.
Ikkinchi muammo ham bor. "Yo'q" qiymatning ichidan ma'lumot o'qimoqchi bo'lsangiz, dastur xato berib to'xtaydi. Bu darsda ikkala muammoning yechimini ko'ramiz.
2. ?? — nullish coalescing
2.1 Faqat null va undefined uchun zaxira
Nullish — "null yoki undefined" degani. Inglizcha "nullga o'xshash" ma'nosida. null va undefined — ikkalasi ham nullish, boshqa hech bir qiymat nullish emas.
Nullish coalescing operatori (??) — chap tomon nullish bo'lsa, o'ng tomonni qaytaradi. Aks holda chap tomonning o'zini. Uni undefined va null darsida qisqa ko'rgan edik — endi to'liq o'rganamiz. "Coalescing" — "birlashtirish" degani, lekin nomni eslab qolish shart emas. Ko'pchilik uni shunchaki "ikki so'roq" deydi.
O'xshatish: pochta qutisi. || qutini ochganda ichida bo'sh konvert bo'lsa ham "xat yo'q" deydi. ?? esa faqat quti umuman bo'sh bo'lsa "xat yo'q" deydi. Bo'sh konvert ham — xat.
Choyxona misolini tuzatamiz:
const tanlanganShakar = 0;
const shakar = tanlanganShakar ?? 2;
console.log(shakar); // 0Endi mijoz shakarsiz choy oladi. 0 nullish emas, shuning uchun ?? uni o'zgartirmadi.
Mijoz hech narsa tanlamagan bo'lsa-chi? Unda qiymat undefined bo'ladi va zaxira ishlaydi:
let tanlanganShakar;
const shakar = tanlanganShakar ?? 2;
console.log(shakar); // 22.2 ?? va ||: yonma-yon
Farqni bitta jadvalda ko'ramiz. Har bir qatorda x || "zaxira" va x ?? "zaxira" natijasi:
x qiymati |
"yoki" bilan | ?? bilan |
|---|---|---|
null |
"zaxira" |
"zaxira" |
undefined |
"zaxira" |
"zaxira" |
0 |
"zaxira" |
0 |
"" |
"zaxira" |
"" |
false |
"zaxira" |
false |
NaN |
"zaxira" |
NaN |
"Ali" |
"Ali" |
"Ali" |
Ko'ryapsizmi? Farq faqat o'rtadagi to'rt qatorda — 0, "", false va NaN da. Ular falsy, lekin nullish emas.
Kodda tekshiramiz:
console.log(0 || 100); // 100
console.log(0 ?? 100); // 0
console.log(false || "zaxira"); // zaxira
console.log(false ?? "zaxira"); // false
console.log(null ?? "zaxira"); // zaxiraBo'sh satr bilan ham xuddi shunday. ?? uni saqlab qoladi:
const izoh = "";
console.log("Izoh:", izoh ?? "izoh yo'q"); // Izoh:
console.log("Izoh:", izoh || "izoh yo'q"); // Izoh: izoh yo'qBirinchi qatorda "Izoh:" dan keyin hech narsa yo'q — bo'sh satr o'zgarmay chiqdi.
O'zingiz to'ldiring: 0 ?? 7 ning natijasi [:0], undefined ?? 7 niki esa [:7].
2.3 Qachon ??, qachon ||?
Ikkalasi ham kerak — vazifasi har xil.
| Vaziyat | Tanlov |
|---|---|
0, "" yoki false — haqiqiy qiymat |
?? |
| Bo'sh satr ham "yo'q" deb hisoblansin | || |
?? uchun misollar: narx (0 — bepul), soni (0 ta), ovoz balandligi (0 — o'chirilgan), "bildirishnoma yoqilganmi?" (false).
|| uchun misol: foydalanuvchi ismini bo'sh qoldirdi. Uni "Mehmon" deb chaqirish mantiqan to'g'ri — bo'sh ism bilan salomlashish g'alati.
Shubha bo'lsa — ?? ni tanlang. U faqat haqiqiy "yo'qlik"ka javob beradi va kutilmagan almashtirish qilmaydi.
2.4 Zanjir va qisqa tutashuv
?? ham zanjir bo'la oladi. Birinchi nullish bo'lmagan qiymat olinadi:
let shaxsiyNarx;
const aksiyaNarxi = null;
const odatiyNarx = 12000;
console.log(shaxsiyNarx ?? aksiyaNarxi ?? odatiyNarx); // 12000?? ham && va || kabi qisqa tutashuv qiladi. Chap tomon nullish bo'lmasa, o'ng tomon umuman bajarilmaydi:
"Ali" ?? console.log("Bu chiqmaydi");
null ?? console.log("Bu chiqadi");Konsolda:
Bu chiqadiTekshirib ko'ring:
const chegirma = 0;bo'lsa,console.log(chegirma ?? 5000)vaconsole.log(chegirma || 5000)nima chiqaradi?
Javob
Birinchisi 0, ikkinchisi 5000. ?? faqat null va undefined da zaxiraga o'tadi, 0 esa ular qatoriga kirmaydi. || esa 0 ni falsy deb, zaxirani oldi. Agar "chegirma yo'q" ma'nosida 0 qo'yilgan bo'lsa, || xato natija beradi.
3. ?. — optional chaining
3.1 Obyektni eslaymiz
?. obyekt bilan ishlaydi. Obyektni ma'lumot turlari darsida ko'rgan edik: bir nechta qiymatni nomlari bilan birga saqlaydigan quti. Eslab olamiz (to'liq — obyektlar darsida):
const buyurtma = { taom: "Plov", narx: 35000 };
console.log(buyurtma.taom); // Plov
console.log(buyurtma.narx); // 35000
console.log(buyurtma.ichimlik); // undefined- Jingalak qavs
{ }ichidanom: qiymatjuftliklari yoziladi, vergul bilan ajratiladi. - Har bir juftlik — xususiyat (property).
taomvanarx—buyurtmaning xususiyatlari. - Xususiyat nuqta bilan olinadi:
buyurtma.taom— "buyurtmaning taomi". - Yo'q xususiyatni so'rasangiz, xato chiqmaydi — shunchaki
undefinedkeladi.
Hozircha shu yetarli.
3.2 Muammo: "yo'q"ning ichiga qarash
Endi mijoz hali hech narsa buyurtma qilmagan. Buyurtma o'rnida null turibdi:
const buyurtma = null;
console.log(buyurtma.taom);
console.log("Bu qator ishlamaydi");TypeError: Cannot read properties of null (reading 'taom')Tarjimasi: "null ning xususiyatlarini o'qib bo'lmaydi (taom ni o'qishda)". null — quti emas, "hech narsa". Hech narsaning ichida taom bo'lmaydi. JavaScript xato beradi va dastur shu joyda to'xtaydi — keyingi qator ham ishlamaydi.
undefined bilan ham xuddi shunday: Cannot read properties of undefined. Bu xatoni undefined va null darsida ko'rgan edik — JavaScript'da eng ko'p uchraydigan xatolardan biri. Endi uning oldini olishni o'rganamiz.
3.3 Yechim: ?.
Optional chaining (?.) — "ixtiyoriy zanjir". Nuqta o'rniga ?. yozasiz. Chap tomon nullish bo'lsa, JavaScript o'ng tomonga qaramaydi va darhol undefined qaytaradi. Aks holda oddiy nuqta kabi ishlaydi.
const buyurtma = null;
console.log(buyurtma?.taom); // undefined
console.log("Dastur davom etyapti");Konsolda:
undefined
Dastur davom etyaptiXato yo'q! ?. "buyurtma bormi?" deb so'radi. Javob "yo'q" bo'lgani uchun taom ni qidirmadi.
?. va ?? birga ajoyib ishlaydi. undefined o'rniga tushunarli matn chiqaramiz:
let buyurtma = null;
console.log(buyurtma?.taom ?? "Hali yo'q"); // Hali yo'q
buyurtma = { taom: "Manti", narx: 30000 };
console.log(buyurtma?.taom ?? "Hali yo'q"); // MantiBirinchi holatda buyurtma?.taom — undefined, shuning uchun ?? zaxirani oldi. Ikkinchisida buyurtma bor va ?. oddiy nuqta kabi ishladi.
Diqqat:
?.faqat o'zidan chapdagi qiymatni tekshiradi. Obyekt bor bo'lsa-yu, xususiyat yo'q bo'lsa —?.shart emas, oddiy nuqta hamundefinedberadi (yuqoridagiichimlikmisolini eslang). Xato faqat nuqtadan oldingi qiymatnullyokiundefinedbo'lganda chiqadi.
3.4 ?. ning boshqa shakllari
?. yana ikki ko'rinishda uchraydi. Ular hali o'tilmagan mavzular bilan bog'liq, shuning uchun hozir faqat tanib olsangiz yetarli:
royxat?.[0] // ro'yxat bo'lsa — birinchi element
xabarYubor?.() // funksiya bo'lsa — uni chaqir?.[ ]— massivlar bilan: massivnullbo'lsa, xato o'rnigaundefined.?.()— funksiyalar bilan: funksiya yo'q bo'lsa, chaqirmaydi vaundefinedqaytaradi.
Qoida uchalasida bir xil: ?. dan chapdagi narsa nullish bo'lsa — to'xta, undefined qaytar.
Maslahat:
?.ni hamma joyga qo'yib chiqmang. Qiymat albatta bo'lishi kerak bo'lgan joyda u xatoni yashiradi. Dastur jimundefinedbilan ishlashda davom etadi. Siz esa xatoni kechroq, boshqa joyda topasiz. Shuning uchun?.ni faqat qiymat yo'q bo'lishi normal holat bo'lgan joyda ishlating.
Tekshirib ko'ring:
const mijoz = undefined;bo'lsa,console.log(mijoz?.ism)vaconsole.log(mijoz.ism)nima qiladi?
Javob
Birinchisi undefined chiqaradi: ?. chap tomon nullish ekanini ko'rib, to'xtadi. Ikkinchisi xato beradi: TypeError: Cannot read properties of undefined (reading 'ism'), chunki oddiy nuqta undefined ning ichiga qarashga urindi.
4. Mantiqiy tayinlash: ||=, &&=, ??=
4.1 += ni eslang
Tayinlash operatorlari darsida += ni ko'rgansiz: narx += 1000 — bu narx = narx + 1000 ning qisqa shakli.
Mantiqiy operatorlarning ham shunday qisqa shakli bor. Ular mantiqiy tayinlash operatorlari (logical assignment) deb ataladi:
| Operator | Ma'nosi | Qachon yozadi |
|---|---|---|
a ??= b |
a ?? (a = b) |
a nullish bo'lsa |
a ||= b |
a || (a = b) |
a falsy bo'lsa |
a &&= b |
a && (a = b) |
a truthy bo'lsa |
Oddiy tilda:
??=— "qiymat yo'q bo'lsa, shuni qo'y".||=— "qiymat falsy bo'lsa, shuni qo'y".&&=— "qiymat bor bo'lsa, uni yangisiga almashtir".
4.2 ??= — standart qiymat qo'yish
Ilova sozlamalari. Foydalanuvchi tilni tanlamagan bo'lsa — o'zbekcha bo'lsin:
let til; // hali tanlanmagan
til ??= "uz";
console.log(til); // uztil — undefined, shuning uchun "uz" yozildi. Agar foydalanuvchi allaqachon "ru" ni tanlagan bo'lsa, ??= unga tegmaydi.
Endi ??= va ||= farqini ko'ramiz. Ovoz balandligi 0 — foydalanuvchi ovozni ataylab o'chirgan:
let ovoz = 0;
ovoz ??= 50;
console.log(ovoz); // 0
ovoz ||= 50;
console.log(ovoz); // 50??= 0 ni hurmat qildi. ||= esa uni "yo'q" deb, 50 ga almashtirdi — foydalanuvchining tanlovi yo'qoldi. Xuddi ?? va || dagi farq.
4.3 &&= — faqat qiymat bo'lsa yangilash
&&= kamroq uchraydi. U "qiymat bor bo'lsa, uni o'zgartir; yo'q bo'lsa — tegma" degani.
Bayram kuni har bir mijozning bonusi 5000 so'mga oshadi. Lekin bonusi yo'q (null) mijozga bonus berilmaydi:
let aliBonusi = 20000;
let valiBonusi = null;
aliBonusi &&= aliBonusi + 5000;
valiBonusi &&= valiBonusi + 5000;
console.log(aliBonusi); // 25000
console.log(valiBonusi); // nullvaliBonusi falsy, shuning uchun o'ng tomon bajarilmadi. Oddiy valiBonusi = valiBonusi + 5000 yozganimizda nima bo'lardi? null + 5000 — 5000, ya'ni Vali kutilmaganda bonus olardi.
4.4 Nozik detal: keraksiz tayinlash bo'lmaydi
a ||= b va a = a || b deyarli bir xil. Lekin farq bor: ||= tayinlashni faqat kerak bo'lganda bajaradi. Bu qisqa tutashuvning natijasi.
Buni const bilan ko'rish mumkin. const ga qayta qiymat yozib bo'lmaydi. Lekin tayinlash kerak bo'lmasa, xato ham chiqmaydi:
const shahar = "Toshkent";
shahar ||= "Samarqand";
console.log(shahar); // Toshkentshahar truthy — tayinlash umuman bajarilmadi, xato yo'q. Qiymat falsy bo'lsa esa tayinlashga urinadi:
const shahar = "";
shahar ||= "Samarqand";TypeError: Assignment to constant variable.Tarjimasi: "o'zgarmas o'zgaruvchiga qiymat tayinlash". Xulosa: mantiqiy tayinlash operatorlarini let bilan ishlating — ular o'zgaruvchini o'zgartirish uchun.
Tekshirib ko'ring:
let soni = 0;bo'lsa,soni ??= 10;vasoni ||= 10;dan keyinsoniqiymati qanday bo'ladi (har birini alohida bajarsak)?
Javob
soni ??= 10 dan keyin — 0, chunki 0 nullish emas. soni ||= 10 dan keyin — 10, chunki 0 falsy. Qiymat nol bo'lishi mumkin bo'lgan joyda ??= xavfsizroq.
5. Ko'p uchraydigan xatolar
5.1 ?? ni || yoki && bilan qavssiz aralashtirish
const ism = null;
const taxallus = "";
const murojaat = ism ?? taxallus || "Mehmon";SyntaxError: Unexpected token '||'Tarjimasi: "kutilmagan belgi: ||". Nega aynan ||? JavaScript'da ?? ni || yoki && bilan qavssiz birga yozish taqiqlangan. Chunki qaysi biri avval bajarilishi odamlar uchun chalkash. JavaScript ism ?? taxallus ni o'qib, keyin || ni ko'rdi va to'xtadi.
Tuzatish — qavs bilan niyatingizni aniq ko'rsating:
const ism = null;
const taxallus = "";
const murojaat = (ism ?? taxallus) || "Mehmon";
console.log(murojaat); // Mehmon5.2 ?. ni tayinlashning chap tomoniga yozish
?. faqat o'qish uchun. U bilan qiymat yozib bo'lmaydi:
let buyurtma = null;
buyurtma?.taom = "Lag'mon";SyntaxError: Invalid left-hand side in assignmentTarjimasi: "tayinlashning chap tomoni noto'g'ri". = ning chap tomonida qiymat yoziladigan aniq joy bo'lishi kerak. buyurtma?.taom esa undefined bo'lib qolishi mumkin — undefined ga yozib bo'lmaydi.
5.3 E'lon qilinmagan o'zgaruvchi bilan ?.
?. faqat null va undefined dan himoya qiladi. Umuman e'lon qilinmagan nomdan himoya qilmaydi:
console.log(mijozz?.ism);ReferenceError: mijozz is not definedTarjimasi: "mijozz aniqlanmagan". Bu yerda nom xato yozilgan — ikkita z. ?. bunday xatoni yashirmaydi, va bu yaxshi: nomdagi xatoni darhol ko'rasiz.
5.4 ?? o'rniga || yozib, 0 ni yo'qotish
Narx, soni, ball, foiz — nol bo'lishi mumkin bo'lgan har qanday son uchun || zaxira xavfli. Bunday joyda doim ?? yoki ??= ishlating.
6. Mashqlar
1-mashq (oson): ?? yoki ||?
Ishga tushirmasdan natijani yozing, keyin tekshiring.
console.log(null ?? "A");
console.log(0 ?? "B");
console.log(0 || "C");
console.log(false ?? "D");
console.log(undefined || "E");
console.log("Nodira" ?? "F");Yechim
console.log(null ?? "A"); // A
console.log(0 ?? "B"); // 0
console.log(0 || "C"); // C
console.log(false ?? "D"); // false
console.log(undefined || "E"); // E
console.log("Nodira" ?? "F"); // Nodira?? faqat null va undefined da o'ng tomonga o'tadi. 0 va false — nullish emas, shuning uchun ular o'zi qaytdi. || esa 0 ni falsy deb tashlab ketdi.
2-mashq (o'rta): Ilova sozlamalari
Foydalanuvchi sozlamalari:
let ovoz = 0; // ataylab o'chirilgan
let tema; // tanlanmagan
let shrift = null; // tozalanganUchala o'zgaruvchiga ??= bilan standart qiymat bering: ovoz — 50, tema — "yorug'", shrift — 16. Keyin uchalasini console.log("Ovoz:", ovoz) kabi chiqaring.
Qaysi biri o'zgarmay qoladi va nega?
Yechim
let ovoz = 0;
let tema;
let shrift = null;
ovoz ??= 50;
tema ??= "yorug'";
shrift ??= 16;
console.log("Ovoz:", ovoz); // Ovoz: 0
console.log("Tema:", tema); // Tema: yorug'
console.log("Shrift:", shrift); // Shrift: 16ovoz o'zgarmadi: 0 — nullish emas, bu foydalanuvchining tanlovi. tema (undefined) va shrift (null) standart qiymat oldi. Agar ||= ishlatganingizda, ovoz 50 ga qaytib qolardi.
3-mashq (qiyin): Yetkazib berish narxi
Onlayn do'konda yetkazib berish narxi yetkazish obyektida saqlanadi. Ba'zan yetkazish ma'lumoti umuman kelmaydi (null). Bunda odatiy narx — 15000 so'm. Narx 0 bo'lsa — yetkazish bepul, va 0 saqlanib qolishi kerak.
let yetkazish = { narx: 0 };?.va??bilan narxni oling va chiqaring. Natija0bo'lishi kerak.yetkazishninullqilib, xuddi shu ifodani yana chiqaring. Natija15000bo'lishi kerak.- Xuddi shu ifodani
??o'rniga||bilan yozib, birinchi holatda nima chiqishini tekshiring. Qaysi biri to'g'ri?
Ishora: xususiyat nuqta bilan olinadi (yetkazish.narx), ?. esa nuqtaning xavfsiz ko'rinishi.
Yechim
let yetkazish = { narx: 0 };
console.log(yetkazish?.narx ?? 15000); // 0
console.log(yetkazish?.narx || 15000); // 15000
yetkazish = null;
console.log(yetkazish?.narx ?? 15000); // 15000- Birinchi qator: yetkazish bor, narx
0.??uni saqladi — to'g'ri, yetkazish bepul. - Ikkinchi qator:
||0ni falsy deb, 15000 qo'ydi — mijoz bepul yetkazish o'rniga pul to'laydi. Bu xato. - Uchinchi qator:
yetkazish—null.?.xato bermayundefinedqaytardi,??esa zaxirani oldi.
Agar ?. o'rniga oddiy nuqta yozganingizda, uchinchi qator TypeError berardi.
7. Real ishda
- Serverdan kelgan ma'lumot. Ilova serverdan foydalanuvchi ma'lumotini oladi. Ba'zi maydonlar bo'lmasligi mumkin.
javob?.foydalanuvchi?.ism ?? "Noma'lum"kabi qator real loyihalarda juda ko'p. Server bilan ishlashni kursning keyingi qismlarida o'rganamiz. - Sozlamalar. Kutubxonalar sozlamalarni
??=bilan to'ldiradi: foydalanuvchi bergan qiymat saqlanadi, berilmagani standart qiymat oladi. - Brauzerlar.
??va?.2020-yilda (ES2020), mantiqiy tayinlash 2021-yilda (ES2021) tilga qo'shilgan. Barcha zamonaviy brauzerlar va Node.js ularni qo'llaydi. Eski kodlarda ularning o'rnigax !== null && x !== undefinedkabi uzun tekshiruvlarni ko'rishingiz mumkin. - Intervyu. "
??va||farqi nima?" — juda mashhur savol. Javob: "||hamma falsy qiymatda zaxiraga o'tadi,??faqatnullvaundefinedda. Shuning uchun0 || 5—5,0 ?? 5esa —0."
Xulosa
a ?? b—afaqatnullyokiundefinedbo'lsabni oladi.0,""vafalsesaqlanib qoladi.||— "falsymi?" deb so'raydi,??— "umuman bormi?" deb so'raydi. Son uchun zaxira bersangiz —??.a?.b—anullish bo'lsa, xato o'rnigaundefinedqaytaradi. Shakllari:?.,?.[ ],?.().??=,||=,&&=— mantiqiy tayinlash. Tayinlash faqat kerak bo'lganda bajariladi.??ni||/&&bilan birga yozganda qavs majburiy.?.bilan qiymat yozib bo'lmaydi.
Keyingi dars: Ternary, vergul, void va operatorlar ustuvorligi — bitta qatorda ikki qiymatdan birini tanlash va operatorlar qaysi tartibda bajarilishini o'rganamiz.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!