Кошумча чынжырчалоо ?.
- арадагы касиеттердин бири жок болсо да, уя салынган объект касиеттерине жетүүнүн коопсуз жолу.
"Жок свойства" маселеси
Эгер сиз жаңы эле окуу куралын окуп жана JavaScript үйрөнө баштаган болсоңуз, анда көйгөй сизге таасирин тийгизбеши мүмкүн, бирок бул абдан кеңири таралган.
user
Мисал катары, биздин колдонуучулар тууралуу маалыматты камтыган объекттер бар дейли .
Биздин колдонуучулардын көбү user.address
көчө мүлкүндө даректери бар user.address.street
, бирок алардын айрымдары андай эмес.
Бул учурда, биз алууга аракет кылганда user.address.street
жана колдонуучу дареги жок болсо, биз ката алабыз:
@A@let user = {}; // пользователь без свойства "address"
alert(user.address.street); // Ошибка!@A@
Бул күтүлгөн жыйынтык. JavaScript ушундай иштейт. user.address
Анын мааниси бар болгондуктан undefined
, алуу аракети user.address.street
ишке ашпай калат.
undefined
Көптөгөн практикалык учурларда, биз катанын ордуна бул жакка жетүүнү туура көрөбүз (бул "көчө жок" дегенди билдирет).
... Же дагы бир мисал. Веб-иштеп чыгууда биз веб-баракчанын элементине туура келген объектти , мисалы, атайын ыкма чакыруусу менен ала алабыз document.querySelector('.elem')
жана ал null
мындай элемент жок болгондо кайтып келет.
@A@// document.querySelector('.elem') равен null, если элемента нет
let html = document.querySelector('.elem').innerHTML; // ошибка, если он равен null@A@
Дагы бир жолу, эгерде элемент жок болсо, биз .innerHTML
y касиетине кирүү боюнча ката алабыз null
. Ал эми кээ бир учурларда элементтин жоктугу нормалдуу болсо, биз катадан качууну жана html = null
натыйжа катары кабыл алууну каалайбыз.
Муну кантип кыла алабыз?
if
Ачык чечим, анын менчигине кирүүдөн мурун же шарттуу оператор менен маанини текшерүү болот ?
, мисалы:
@A@let user = {};
alert(user.address ? user.address.street : undefined);@A@
Ал иштейт, эч кандай ката жок... Бирок, бул өтө эле елегалдуу. Көрүнүп тургандай, "user.address"
ал коддо эки жолу пайда болот.
Бул жерде ал кандай болот document.querySelector
:
@A@let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;@A@
Көрүнүп тургандай, бул жерде элементти издөө document.querySelector('.elem')
эки жолу чакырылат, бул абдан жакшы эмес.
Көбүрөөк уяланган касиеттер үчүн, бул дагы анча сулуу эмес, анткени көбүрөөк кайталоо талап кылынат.
Мисалы, эсептеп көрөлү user.address.street.name
.
user.address
Биз экөөнү тең текшеришибиз керек user.address.street
:
@A@let user = {}; // у пользователя нет адреса
alert(user.address ? user.address.street ? user.address.street.name : null : null);@A@
Бул жөн эле коркунучтуу, кимдир бирөө мындай кодду түшүнө албай калышы мүмкүн.
Муну колдонуу менен жазуунун бир аз жакшы жолу бар &&
:
@A@let user = {}; // пользователь без адреса
alert( user.address && user.address.street && user.address.street.name ); // undefined (без ошибки)@A@
Логикалык ЖАНА &&
бүт мүлк жолу аркылуу бардык компоненттердин бар экендигин камсыздайт (эгер андай болбосо, баалоо токтойт), бирок идеалдуу эмес.
Көрүнүп тургандай, мүлктүн аталыштары дагы эле коддо кайталанат. Мисалы, жогорудагы коддо user.address
үч жолу пайда болот.
Ошондуктан тилге кошумча чынжыр кошулду ?.
. Бул маселени чечүү үчүн - бир жолу жана биротоло!
Кошумча чынжыр
Кошумча чынжыр ?.
баалоону токтотот жана undefined
мурунку маани же ге ?.
барабар болсо кайтарат .undefined
null
Кийинчерээк бул макалада, кыска болуу үчүн, биз бир нерсе "бар" деп айтабыз, эгерде ал жок болсо null
жана жок болсо undefined
.
Башка сөз менен айтканда value?.prop
,:
value.prop
баалуулук бар болсо сыяктуу иштейтvalue
,- антпесе (
value
ге барабар болгондоundefined/null
) ал кайтып келетundefined
.
user.address.street
Бул жерде колдонуу үчүн коопсуз жол болуп саналат ?.
:
let user = {}; // пользователь без адреса
@A@
alert( user?.address?.street ); // undefined (без ошибки)@A@
Код кыска жана түшүнүктүү, эч кандай кайталоо жок.
Жана бул жерде бир мисал келтирилген document.querySelector
:
@A@let html = document.querySelector('.elem')?.innerHTML; // будет undefined, если элемента нет@A@
Даректи окуу user?.address
объект user
жок болсо дагы иштейт:
@A@let user = null;
alert( user?.address ); // undefined
alert( user?.address.street ); // undefined@A@
Эскертүү, синтаксис ?.
өзүнө чейинки маанини милдеттүү кылат, бирок андан кийин эч нерсе кылбайт.
Мисалы, жазууда коопсуз болуу user?.address.street.name
?.
( жана бул учурда кайтарып берет ), бирок бул үчүн гана туура . Кийинки касиеттерге кадимки жол менен жетүү. Эгерде биз алардын айрымдарынын кошумча болушун кааласак, анда биз көбүрөөк менен алмаштырышыбыз керек болот .user
null/undefined
undefined
user
.
?.
Биз ?.
аны бир нерсе жок болгон жерде гана колдонушубуз керек.
Мисалы, биздин кодубуздун логикасына ылайык, объект user
бар болушу керек, бирок address
милдеттүү эмес болсо, анда биз жазышыбыз керек user.address?.street
, бирок user?.address?.street
.
Бул учурда, эгерде ал күтүлбөгөн жерден user
чыкса undefined
, биз бул жөнүндө программалык катаны көрүп, аны оңдойбуз. Болбосо, өтө көп колдонулса ?.
, мүчүлүштүктөр болбошу керек жерде жабылып калышы мүмкүн, бул аларды оңдоону кыйындатат.
?.
жарыяланышы керекЭгерде өзгөрмө user
такыр жок болсо, ал user?.anything
катага алып келет:
@A@// ReferenceError: user is not defined
user?.address;@A@
Өзгөрмө жарыяланышы керек (мисалы, let/const/var user
функциянын параметри катары же катары). Кошумча чынжыр жарыяланган өзгөрмөлөр менен гана иштейт.
Кыскартылган эсептөө
Мурда айтылгандай, ?.
сол жагы жок болсо, дароо баа берүүнү токтотот.
Демек, ?.
андан кийин кандайдыр бир функция чакырыктары же операциялар болсо, алар болбойт.
Мисалы:
@A@let user = null;
let x = 0;
user?.sayHi(x++); // нет "user", поэтому выполнение не достигает вызова sayHi и x++
alert(x); // 0, значение не увеличилось@A@
Башка колдонулушу: ?.(), ?.[]
Кошумча чынжыр ?.
оператор эмес, функциялар жана чарчы кашаалар менен иштеген атайын синтаксис конструкциясы.
Мисалы, ?.()
жок болушу мүмкүн болгон функцияны чакыруу үчүн колдонулат.
Төмөнкү коддо биздин кээ бир колдонуучулардын ыкмасы бар, admin
ал эми кээ бирлери жок:
@A@let userAdmin = {
admin() {
alert("Я админ");
}
};
let userGuest = {};
userAdmin.admin?.(); // Я админ
userGuest.admin?.(); // ничего не произойдет (такого метода нет)@A@
userAdmin.admin
Бул жерде эки сапта тең объектти алуу үчүн алгач чекит ( ) колдонобуз, admin
анткени объект user
бар деп ойлойбуз, андыктан аны окуу коопсуз.
Андан кийин ?.()
ал сол тарапты текшерет: эгерде функция admin
бар болсо, анда ал иштетилет (бул . үчүн туура userAdmin
). Болбосо (үчүн userGuest
), эсептөө катасыз токтойт.
Эгерде биз чекиттин ордуна менчикке кирүү үчүн ?.[]
кашааларды колдонгубуз келсе, синтаксис иштейт . Мурунку учурлардагыдай эле, ал жок болушу мүмкүн болгон объекттен касиетти коопсуз окууга мүмкүндүк берет.[]
.
@A@let key = "firstName";
let user1 = {
firstName: "John"
};
let user2 = null;
alert( user1?.[key] ); // John
alert( user2?.[key] ); // undefined
?.
Ошондой эле биз менен колдоно алабыз delete
:
delete user?.name; // удаляет user.name если пользователь существует@A@
?.
, бирок жаза албайбызКошумча чынжыр ?.
тапшырманын сол тарабында эч кандай мааниге ээ эмес.
Мисалы:
@A@let user = null;
user?.name = "John"; // Ошибка, не работает
// то же самое что написать undefined = "John"@A@
Бардыгы
Кошумча чынжыр синтаксисинин ?.
үч формасы бар:
obj?.prop
–obj.prop
эгерobj
бар болсо кайтарат, болбосоundefined
.obj?.[prop]
–obj[prop]
эгерobj
бар болсо кайтарат, болбосоundefined
.obj.method?.()
–obj.method()
эгерobj.method
бар болсо чакырат, болбосо кайтаратundefined
.
Көрүнүп тургандай, алардын бардыгы жөнөкөй жана колдонууга оңой. ?.
сол жагын текшерет null/undefined
жана эгер жок болсо, эсептөөнү улантат.
Чынжырчалуу ?.
уяланган касиеттерге коопсуз кирүүгө мүмкүндүк берет.
Бирок, биз аны ?.
этияттык менен колдонушубуз керек, ал сол жагы жок деп коддук логика менен кабыл алынган жерде гана. Программалоо каталары пайда болсо, бизден жашырбашы үчүн.