Den valgfrie sammenkædning ?. er en sikker måde at få adgang til indlejrede objekt-egenskaber på, selvom en mellemliggende egenskab ikke eksisterer.
Problemet med “ikke-eksisterende egenskaber”
Hvis du lige er begyndt at læse vejledningen og lære JavaScript, har problemet måske ikke ramt dig endnu, men det er ret almindeligt.
Som et eksempel, lad os sige, at vi har user-objekter, der indeholder oplysninger om vores brugere.
De fleste af vores brugere har adresser i user.address-egenskaben, med gaden user.address.street, men nogle har ikke angivet dem.
I så fald, når vi forsøger at få user.address.street, og brugeren tilfældigvis ikke har en adresse, får vi en fejl:
let user = {}; // en bruger uden "address"-egenskab
alert(user.address.street); // Fejl!
Det er det forventede resultat. JavaScript fungerer sådan. Da user.address er undefined, mislykkes et forsøg på at få user.address.street med en fejl.
I mange praktiske tilfælde foretrækker vi at få undefined i stedet for en fejl her (betydende “ingen gade”).
…og et andet eksempel. I webudvikling kan vi få et objekt, der svarer til et websideelement ved hjælp af et specielt metodekald, såsom document.querySelector('.elem'), og det returnerer null, når der ikke er et sådant element.
// document.querySelector('.elem') er null, hvis der ikke er et element
let html = document.querySelector('.elem').innerHTML; // fejl, hvis det er null
Hvis elementet ikke findes, får vi en fejl, når vi forsøger at få adgang til .innerHTML-egenskaben af null. Og i nogle tilfælde, når fraværet af elementet er normalt, vil vi gerne undgå fejlen og blot acceptere html = null som resultatet.
Hvordan kan vi gøre dette?
Den oplagte løsning ville være at tjekke værdien ved hjælp af if eller den betingede operator ?, før vi får adgang til dens egenskab, sådan her:
let user = {};
alert(user.address ? user.address.street : undefined);
Det virker, der er ingen fejl… Men det er ret upraktisk. Som du kan se, optræder "user.address" to gange i koden.
Her er hvordan det samme ville se ud for document.querySelector:
let html = document.querySelector('.elem') ? document.querySelector('.elem').innerHTML : null;
Vi kan se, at element-søgningen document.querySelector('.elem') faktisk kaldes to gange her. Ikke godt.
For mere dybt indlejrede egenskaber bliver det endnu grimmere, da flere gentagelser er nødvendige.
F.eks. lad os få user.address.street.name på en lignende måde.
let user = {}; // user har ingen adresse
alert(user.address ? user.address.street ? user.address.street.name : null : null);
Det er skrækkeligt!. Flere kan endda have problemer med bare at forstå sådan kode.
Der er en lidt bedre måde at skrive det på ved hjælp af &&-operatoren:
let user = {}; // user har ingen adresse
alert( user.address && user.address.street && user.address.street.name ); // undefined (ingen fejl)
At “AND’e” hele stien til egenskaben sikrer, at alle komponenter eksisterer (hvis ikke, stopper evalueringen), men det er heller ikke ideelt.
Som du kan se, optræder egenskabsnavne stadig flere gange i koden. F.eks. i koden ovenfor optræder user.address tre gange.
Derfor blev den valgfrie kædning ?. tilføjet til sproget. For at løse dette problem én gang for alle!
Valgfri kædning
Den valgfrie kædning ?. stopper evalueringen, hvis værdien før ?. er undefined eller null og returnerer undefined.
Fremover i denne artikel, for korthedens skyld, vil vi sige, at noget “eksisterer”, hvis det ikke er null og ikke undefined.
Med andre ord, value?.prop:
- fungerer som
value.prop, hvisvalueeksisterer, - ellers (når
valueerundefined/null) returnerer detundefined.
Her er den sikre måde at få adgang til user.address.street ved hjælp af ?.:
let user = {}; // user har ingen adresse
alert( user?.address?.street ); // undefined (ingen fejl)
Koden er kort og ren, der er ingen duplikation overhovedet.
Her er et eksempel med document.querySelector: