Ixtiyoriy zanjir ?. ichma-ich obyekt xossalariga xavfsiz kirish usuli, hatto oraliq xossa mavjud boâlmasa ham.
âMavjud boâlmagan xossaâ muammosi
Agar siz hozirgina oâquv qoâllanmasini oâqishni va JavaScript oârganishni boshlaganingiz boâlsa, ehtimol bu muammo sizga taâsir qilmagan boâlsa ham, u juda keng tarqalgan.
Misol sifatida, bizda foydalanuvchilar haqidagi maâlumotlarni saqlaydigan user obyektlari bor deb faraz qilaylik.
Foydalanuvchilarimizning koâpchisida user.address xossasida manzil bor, koâcha user.address.street bilan, lekin baâzilari ularni taqdim etmagan.
Bunday holda, biz user.address.street ni olishga harakat qilganimizda va foydalanuvchida manzil boâlmasa, xatoga duch kelamiz:
let user = {}; // "address" xossasi bo'lmagan foydalanuvchi
alert(user.address.street); // Xato!
Bu kutilgan natija. JavaScript shunday ishlaydi. user.address undefined boâlgani uchun user.address.street ni olishga harakat xato bilan tugaydi.
Koâplab amaliy hollarda biz bu yerda xato oârniga undefined olishni afzal koâramiz (âkoâcha yoâqâ maânosida).
â¦Va yana bir misol. Veb-dasturlashda biz document.querySelector('.elem') kabi maxsus usul chaqiruvi orqali veb-sahifa elementiga mos keladigan obyektni olishimiz mumkin va bunday element boâlmasa null qaytaradi.
// document.querySelector('.elem') element bo'lmasa null
let html = document.querySelector(".elem").innerHTML; // null bo'lsa xato
Yana, agar element mavjud boâlmasa, biz null ning .innerHTML ga kirishda xato olamiz. Va baâzi hollarda, element yoâqligi normal boâlganda, biz xatolardan qochmoqchimiz va shunchaki natija sifatida html = null ni qabul qilmoqchimiz.
Buni qanday qilishimiz mumkin?
Aniq yechim xossasiga kirishdan oldin if yoki shartli operator ? dan foydalanib qiymatni tekshirish boâladi:
let user = {};
alert(user.address ? user.address.street : undefined);
Bu ishlaydi, xato yoâq⦠Lekin juda nafis emas. Koârib turganingizdek, "user.address" kodda ikki marta uchraydi. Chuqurroq joylashtirilgan xossalar uchun bu muammoga aylanadi, chunki koâproq takrorlash talab qilinadi.
Masalan, user.address.street.name ni olishga harakat qilaylik.
Biz ham user.address ni ham user.address.street ni tekshirishimiz kerak:
let user = {}; // foydalanuvchida manzil yo'q
alert(
user.address ? (user.address.street ? user.address.street.name : null) : null
);
Bu dahshatli, kimdir bunday kodni tushunishda muammo boâlishi mumkin.
Bunga qaramang, uni && operatori yordamida yozishning yaxshi usuli bor:
let user = {}; // foydalanuvchida manzil yo'q
alert(user.address && user.address.street && user.address.street.name); // undefined (xato yo'q)
Xossaga yoâlning barcha qismlarini VA qilish barcha komponentlar mavjudligini taâminlaydi (agar boâlmasa, baholash toâxtaydi), lekin bu ham ideal emas.
Koârib turganingizdek, xossa nomlari kodda hali ham takrorlanmoqda. Masalan, yuqoridagi kodda user.address uch marta uchraydi.
Shuning uchun tilga ixtiyoriy zanjir ?. qoâshildi. Bu muammoni bir marta va butunlay hal qilish uchun!
Ixtiyoriy zanjir
Ixtiyoriy zanjir ?. agar ?. dan oldingi qiymat undefined yoki null boâlsa baholashni toâxtatadi va undefined qaytaradi.
Ushbu maqolada qisqalik uchun biz biror narsa null va undefined boâlmasa âmavjudâ deb ataymiz.
Boshqacha qilib aytganda, value?.prop:
- agar
valuemavjud boâlsa,value.propsifatida ishlaydi, - aks holda (
valueundefined/nullboâlganda)undefinedqaytaradi.
?. dan foydalanib user.address.street ga xavfsiz kirish usuli:
let user = {}; // foydalanuvchida manzil yo'q
alert(user?.address?.street); // undefined (xato yo'q)
Kod qisqa va toza, umuman takrorlash yoâq.
user?.address bilan manzilni oâqish user obyekti mavjud boâlmasa ham ishlaydi:
let user = null;
alert(user?.address); // undefined
alert(user?.address.street); // undefined
Eâtibor bering: ?. sintaksisi undan oldingi qiymatni ixtiyoriy qiladi, lekin boshqa hech narsani emas.
Masalan, user?.address.street.name da ?. user ning xavfsiz ravishda null/undefined boâlishiga imkon beradi (va bu holda undefined qaytaradi), lekin bu faqat user uchun. Keyingi xossalarga oddiy tarzda kiriladi. Agar ulardan baâzilari ixtiyoriy boâlishini istasak, koâproq . ni ?. bilan almashtirishimiz kerak.
Biz ?. ni faqat biror narsa mavjud boâlmasligi normal boâlgan joylarda ishlatishimiz kerak.
Masalan, agar bizning kodlash mantiqimizga koâra user obyekti mavjud boâlishi kerak, lekin address ixtiyoriy boâlsa, biz user.address?.street yozishimiz kerak, user?.address?.street emas.
Shunday qilib, agar user xato tufayli undefined boâlib qolsa, biz bu haqda dasturlash xatosini koâramiz va uni tuzatamiz. Aks holda, kodlash xatolari kerakli boâlmagan joyda jim qolishi va disk raskadka qilish qiyinlashishi mumkin.
?.dan oldingi oâzgaruvchi eâlon qilingan boâlishi kerakAgaruseroâzgaruvchisi umuman boâlmasa,user?.anything xatoni keltirib chiqaradi:
// ReferenceError: user is not defined
user?.address;
Oâzgaruvchi eâlon qilingan boâlishi kerak (masalan, let/const/var user yoki funksiya parametri sifatida). Ixtiyoriy zanjir faqat eâlon qilingan oâzgaruvchilar uchun ishlaydi.
Qisqa tutashuv
Ilgari aytilganidek, chap qism mavjud boâlmasa ?. darhol toâxtaydi (âqisqa tutashadiâ).
Shuning uchun, agar keyingi funksiya chaqiruvlari yoki yon taâsirlar boâlsa, ular sodir boâlmaydi.
Masalan:
let user = null;
let x = 0;
user?.sayHi(x++); // "sayHi" yo'q, shuning uchun bajarilish x++ ga yetmaydi
alert(x); // 0, qiymat oshirilmadi
Boshqa variantlar: ?.(), ?.[]
Ixtiyoriy zanjir ?. operator emas, balki funksiyalar va kvadrat qavslar bilan ham ishlaydigan maxsus sintaksis konstruksiyasidir.
Masalan, ?.() mavjud boâlmasligi mumkin boâlgan funksiyani chaqirish uchun ishlatiladi.
Quyidagi kodda foydalanuvchilarimizning baâzilarida admin usuli bor, baâzilarida yoâq:
let userAdmin = {
admin() {
alert("Men adminman");
}
};
let userGuest = {};
userAdmin.admin?.(); // Men adminman
userGuest.admin?.(); // hech narsa (bunday usul yo'q)
Bu yerda ikkala qatorda ham avval nuqtadan foydalanib (userAdmin.admin) admin xossasini olamiz, chunki user obyekti mavjud deb taxmin qilamiz, shuning uchun undan oâqish xavfsiz.
Keyin ?.() chap qismni tekshiradi: agar admin funksiyasi mavjud boâlsa, u ishga tushadi (userAdmin uchun shunday). Aks holda (userGuest uchun) baholash xatosiz toâxtaydi.
?.[] sintaksisi ham ishlaydi, agar biz nuqta . oârniga xossalarga kirish uchun qavslar [] dan foydalanmoqchi boâlsak. Oldingi hollarga oâxshab, u mavjud boâlmasligi mumkin boâlgan obyektdan xavfsiz ravishda xossa oâqishga imkon beradi.
let key = "firstName";
let user1 = {
firstName: "John"
};
let user2 = null;
alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
Shuningdek, biz ?. ni delete bilan ishlatishimiz mumkin:
delete user?.name; // agar user mavjud bo'lsa user.name ni o'chirish
?. ni xavfsiz oâqish va oâchirish uchun ishlatishimiz mumkin, lekin yozish uchun emasIxtiyoriy zanjir ?. tayinlashning chap tomonida foydalanilmaydi.
Masalan:
let user = null;
user?.name = "John"; // Xato, ishlamaydi
// chunki u undefined = "John" ga baholanadi
Bu shunchaki aqlli emas.
Xulosa
Ixtiyoriy zanjir ?. sintaksisi uchta shaklga ega:
obj?.propâ agarobjmavjud boâlsaobj.propni qaytaradi, aks holdaundefined.obj?.[prop]â agarobjmavjud boâlsaobj[prop]ni qaytaradi, aks holdaundefined.obj.method?.()â agarobj.methodmavjud boâlsaobj.method()ni chaqiradi, aks holdaundefinedqaytaradi.
Koârib turganingizdek, ularning barchasi oddiy va foydalanish oson. ?. chap qismni null/undefined uchun tekshiradi va u bunday boâlmasa baholashni davom ettiradi.
?. zanjiri ichma-ich xossalarga xavfsiz kirish imkonini beradi.
Shunga qaramay, biz ?. ni ehtiyotkorlik bilan, faqat chap qismning mavjud boâlmasligi qabul qilinadigan joylarda qoâllashimiz kerak. Shunda u bizdan dasturlash xatolarini yashirmaydi, agar ular sodir boâlsa.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)