Optional Chaining `?.`

Oddiy `{...}` sintaksisi yordamida bitta ob'ekt yaratish mumkin. Ammo ko'pincha ko'p o'xshash ob'ektlarni yaratish kerak bo'ladi, masalan, bir nechta foydalanuvchilar yoki menyu elementlari va hokazo.

Optional Chaining ?.

Yangi Qo'shimcha

Bu tilga yaqinda qo'shilgan. Eski brauzerlar polifillarga ehtiyoj sezishi mumkin.

Optional chaining ?. ichki ob'ekt xususiyatlarini xavfsiz tarzda olish imkonini beradi, hatto oraliq xususiyat mavjud bo'lmasa ham.

"Mavjud bo'lmagan xususiyat" muammosi

Agar siz JavaScript bilan tanishishni boshlagan bo'lsangiz, bu muammo sizni hali ta'sir qilmagan bo'lishi mumkin, ammo bu juda keng tarqalgan.

Misol uchun, bizda foydalanuvchilar haqidagi ma'lumotlarni saqlovchi foydalanuvchi ob'ektlari mavjud.

Ko'p foydalanuvchilarimizning user.address xususiyatida manzillari mavjud, user.address.street bilan ko'rsatilgan, ammo ba'zilari uni taqdim etmagan.

Bunday holatda, user.address.streetni olishga harakat qilganda, foydalanuvchi manzili bo'lmagan bo'lsa, xato olishimiz mumkin:

let user = {}; // "address" xususiyati bo'lmagan foydalanuvchi
 
alert(user.address.street); // Xato!

Bu kutilgan natija. JavaScript shunday ishlaydi. user.address aniqlanmagan bo'lsa, user.address.street olishga harakat qilish xato bilan tugaydi.

Ko'plab amaliy holatlarda, xatoni olish o'rniga undefined olishni afzal ko'ramiz (bu "manzil mavjud emas" degan ma'noni anglatadi).

…va yana bir misol. Veb-ishlab chiqishda, biz maxsus metod chaqiruvi orqali veb sahifa elementiga mos ob'ektni olishimiz mumkin, masalan document.querySelector('.elem'), va agar bunday element bo'lmasa, u null qaytaradi.

// document.querySelector('.elem') element bo'lmasa null bo'ladi
let html = document.querySelector('.elem').innerHTML; // agar null bo'lsa xato

Yana bir bor, agar element mavjud bo'lmasa, null ning .innerHTML xususiyatiga kirish xatoga olib keladi. Ba'zi holatlarda, elementning mavjud bo'lmasligi normal bo'lsa, xatoni oldini olish va natija sifatida html = null qabul qilishni xohlaymiz.

Buni qanday qilish mumkin?

Aniq yechim shunday bo'ladi: qiymatni tekshirib, keyin uning xususiyatiga kirish uchun if yoki shartli operator ? dan foydalanish.

let user = {};
 
alert(user.address ? user.address.street : undefined);

Bu ishlaydi, xato yo'q… Ammo juda nozik emas. Ko'rib turganingizdek, user.address kodda ikki marta paydo bo'ladi.

Mana shunday ko'rinishda document.querySelector uchun:

let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;

Ko'rishimiz mumkin bo'lganidek, elementni qidirish document.querySelector('.elem') aslida ikki marta chaqirilmoqda. Yaxshi emas.

Yana chuqurroq ichki xususiyatlar uchun bu yanada yomonlashadi, chunki ko'proq takrorlash talab etiladi.

Masalan, user.address.street.nameni shunga o'xshash tarzda olish.

let user = {}; // foydalanuvchida manzil yo'q
 
alert(user.address ? (user.address.street ? user.address.street.name : null) : null);

Bu juda yomon, bunday kodni tushunish qiyin bo'lishi mumkin.

Buni && operatoridan foydalanib yaxshiroq yozish mumkin:

let user = {}; // foydalanuvchida manzil yo'q
 
alert(user.address && user.address.street && user.address.street.name); // undefined (xato yo'q)

To'liq yo'lni tekshirish, barcha komponentlarning mavjudligini ta'minlaydi (agar mavjud bo'lmasa, baholash to'xtaydi), ammo hamon ideal emas.

Ko'rib turganingizdek, xususiyat nomlari kodda hali ham takrorlanmoqda. Masalan, yuqoridagi kodda user.address uch marta paydo bo'ladi.

Shuning uchun optional chaining ?. tilga qo'shildi. Bu muammoni bir marta va abadiy hal qilish uchun!

Optional Chaining

Optional chaining ?. baholashni to'xtatadi, agar ?. dan oldingi qiymat undefined yoki null bo'lsa va undefined qaytaradi.

Quyida qisqargan holda, biror narsa “mavjud” bo'lsa, agar u null va undefined bo'lmasa, deb aytamiz.

Boshqacha qilib aytganda, value?.prop:

  • agar value mavjud bo'lsa, value.prop kabi ishlaydi,
  • aks holda (value undefined/null bo'lsa) undefined qaytaradi.

Mana shunday xavfsiz tarzda user.address.streetga kirish:

let user = {}; // foydalanuvchida manzil yo'q
 
alert(user?.address?.street); // undefined (xato yo'q)

Kod qisqa va toza, umuman takrorlanish yo'q.

Mana document.querySelector bilan misol:

let html = document.querySelector('.elem')?.innerHTML; // agar element mavjud bo'lmasa undefined bo'ladi

user?.address bilan manzilni o'qish foydalanuvchi ob'ekti mavjud bo'lmasa ham ishlaydi:

let user = null;
 
alert(user?.address); // undefined
alert(user?.address.street); // undefined

Iltimos, diqqat qiling: ?. sintaksisi faqat oldingi qiymatni ixtiyoriy qiladi, lekin boshqa barcha xususiyatlarga emas.

Masalan, user?.address.street.nameda ?. userni xavfsiz null/undefined bo'lishiga imkon beradi (va bunday holda undefined qaytaradi), ammo bu faqat user uchun. Keyingi xususiyatlarga odatdagi tarzda kiriladi. Agar ba'zi xususiyatlar ixtiyoriy bo'lishi kerak bo'lsa, unda ko'proq . ni ? bilan almashtirish kerak bo'ladi.

Optional Chaining'ni Ortib Borishdan Saqlaning

Biz ?. ni faqat ma'lum bo'lgan holatlarda foydalanishimiz kerak, ya'ni biror narsa mavjud bo'lmasa, qabul qilinadigan holatlarda.

Masalan, agar kod mantiqiga ko'ra user ob'ekti mavjud bo'lishi kerak, lekin address ixtiyoriy bo'lsa, biz user.address?.street deb yozishimiz kerak, lekin user?.address?.street emas.

Shunda, agar user undefined bo'lsa, biz kod xatosini ko'ramiz va uni tuzatamiz. Aks holda, agar biz ?. ni ortiqcha ishlatsak, kod xatolari xatolarga qadar yashirilishi mumkin va xatolarni aniqlash qiyinlashadi.

?. Sintaksisida O'zgaruvchilar E'lon Qilingan Bo'lishi Kerak

Agar umuman user o'zgaruvchisi mavjud bo'lmasa, unda user?.anything xatoni chaqiradi:

// ReferenceError: user is not defined
user?.address;

O'zgaruvchi e'lon qilinishi kerak (masalan, let/const/var user yoki funksiyaning parametr sifatida). Optional chaining faqat e'lon qilingan o'zgaruvchilar uchun ishlaydi.

Qisqartirish

Oldin aytib o'tilganidek, ?. darhol baholashni to'xtatadi (“short-circuits”), agar chap qism mavjud bo'lmasa.

Shunday qilib, ?. dan o'ngdagi boshqa funktsiya chaqiruvlari yoki amallar bajarilmaydi.

Masalan:

let user = null;
let x = 0;
 
user?.sayHi(x++); // "user" yo'q, shuning uchun sayHi chaqirishi va x++ bajarilmaydi
 
alert(x); // 0, qiymat oshirilmagan

Boshqa Variantlar: ?.() va ?.[]

Optional chaining ?. operator emas, balki maxsus sintaktik konstruktsiya bo'lib, bu funksiyalar va kvadrat qavslar bilan ham ishlaydi.

Masalan, ?.() mavjud bo'lmasligi mumkin bo'lgan funktsiyani chaqirish uchun ishlatiladi.

Quyidagi kodda, ba'zi foydalanuvchilarimizda admin metodi mavjud, ba'zilarida esa mavjud emas:

let userAdmin = {
  admin() {
    alert('Men adminman');
  },
};
 
let userGuest = {};
 
userAdmin.admin?.(); // Men adminman
 
userGuest.admin?.(); // hech narsa bo'lmaydi (bunday metod yo'q)

Bu yerda, har ikki qatorimizda ham avval userAdmin.admin nuqtani ishlatamiz, chunki user ob'ekti mavjud deb hisoblaymiz, shuning uchun undan xavfsiz tarzda o'qishimiz mumkin.

So'ngra ?.() chap qismini tekshiradi: agar admin funksiyasi mavjud bo'lsa, u ishlaydi (bu userAdmin uchun shunday). Aks holda (userGuest uchun) baholash xatosiz to'xtaydi.

?.[] sintaksisi ham mavjud, agar xususiyatlarga kirish uchun kvadrat qavslarni [] ishlatmoqchi bo'lsak. Oldingi holatlar bilan o'xshash tarzda, bu ixtiyoriy bo'lishi mumkin bo'lgan ob'ektdan xususiyatlarni xavfsiz tarzda o'qishga imkon beradi.

let key = 'firstName';
 
let user1 = {
  firstName: 'John',
};
 
let user2 = null;
 
alert(user1?.[key]); // John
alert(user2?.[key]); // undefined

Shuningdek, ?. yordamida delete operatoridan foydalanish mumkin:

delete user?.name; // agar user mavjud bo'lsa user.name ni o'chiradi

Biz ?. yordamida xavfsiz o'qish va o'chirishni amalga oshirishimiz mumkin, lekin yozish emas.

Xulosa

Optional chaining ?. sintaksisi uch shaklda mavjud:

  • obj?.prop – agar obj mavjud bo'lsa, obj.prop qaytariladi, aks holda undefined.
  • obj?.[prop] – agar obj mavjud bo'lsa, obj[prop] qaytariladi, aks holda undefined.
  • obj.method?.() – agar obj.method mavjud bo'lsa, obj.method() chaqiriladi, aks holda undefined.

Ko'rib turganimizdek, ularning barchasi to'g'ri va foydalanish uchun oddiy. ?. chap qismini null/undefined uchun tekshiradi va agar shunday bo'lmasa, baholash davom etadi.

?. zanjiri ichki xususiyatlarni xavfsiz tarzda olish imkonini beradi.

Shunga qaramay, biz ?. dan ehtiyotkorlik bilan foydalanishimiz kerak, faqat kod mantiqiga ko'ra, chap qism mavjud bo'lmasligi mumkin bo'lgan holatlarda. Shunda, agar xatolar yuzaga kelsa, ular bizdan yashirilmaydi va ularga tezda e'tibor qaratishimiz mumkin.

Ushbu sahifada

GitHubda tahrirlash