Avastage turvalisem, puhtam ja paindlikum JavaScript'i kood valikulise aheldamise (?.) ja nullilähedase ühendamise (??) abil. Vältige levinud käitusvigu ja käsitlege puuduvaid andmeid elegantselt.
JavaScript'i valikuline aheldamine ja nullilähedane ühendamine: vastupidavate ja paindlike rakenduste ehitamine
Veebiarenduse dünaamilises maailmas suhtlevad JavaScripti rakendused sageli erinevate andmeallikatega, alates REST API-dest kuni kasutajasisendite ja kolmandate osapoolte teekideni. See pidev teabevoog tähendab, et andmestruktuurid ei ole alati etteaimatavad ega täielikud. Üks levinumaid peavalusid, millega arendajad silmitsi seisavad, on katse pääseda ligi objekti omadustele, mis võivad olla null või undefined, mis viib kardetud veani "TypeError: Cannot read properties of undefined (reading 'x')". See viga võib teie rakenduse kokku jooksutada, häirida kasutajakogemust ja jätta teie koodi täis kaitsvaid kontrolle.
Õnneks on kaasaegne JavaScript kasutusele võtnud kaks võimsat operaatorit – valikuline aheldamine (?.) ja nullilähedane ühendamine (??) – mis on spetsiaalselt loodud nende väljakutsete lahendamiseks. Need ES2020-s standardiseeritud funktsioonid võimaldavad arendajatel üle maailma kirjutada puhtamat, vastupidavamat ja tugevamat koodi potentsiaalselt puuduvate andmetega tegelemisel. See põhjalik juhend süveneb mõlemasse operaatorisse, uurides nende funktsionaalsust, eeliseid, täiustatud kasutusjuhtumeid ja seda, kuidas nad sünergiliselt koos töötavad, et luua etteaimatavamaid ja veakindlamaid rakendusi.
Olenemata sellest, kas olete kogenud JavaScripti arendaja, kes ehitab keerulisi ettevõttelahendusi, või alles alustate oma teekonda, valikulise aheldamise ja nullilähedase ühendamise valdamine tõstab oluliselt teie kodeerimisoskust ja aitab teil luua rakendusi, mis käsitlevad elegantselt reaalmaailma andmete ebakindlust.
Probleem: potentsiaalselt puuduvate andmete navigeerimine
Enne valikulise aheldamise ja nullilähedase ühendamise tulekut pidid arendajad pesastatud omadustele turvaliseks juurdepääsuks toetuma paljusõnalistele ja korduvatele tingimuslikele kontrollidele. Vaatleme levinud stsenaariumi: kasutaja aadressiandmetele juurdepääs, mis ei pruugi alati API-st saadud kasutajaobjektis olemas olla.
Traditsioonilised lähenemisviisid ja nende piirangud
1. Loogilise JA (&&) operaatori kasutamine
See oli populaarne tehnika omadustele juurdepääsu lühistamiseks. Kui mõni ahela osa oli väär (falsy), siis avaldis peatuks ja tagastaks selle väära väärtuse.
const user = {
id: 'u123',
name: 'Alice Smith',
contact: {
email: 'alice@example.com',
phone: '123-456-7890'
}
// aadress puudub
};
// Katse saada tänavat kasutaja aadressist
const street = user && user.contact && user.contact.address && user.contact.address.street;
console.log(street); // undefined
const userWithAddress = {
id: 'u124',
name: 'Bob Johnson',
contact: {
email: 'bob@example.com'
},
address: {
street: '123 Main St',
city: 'Metropolis',
country: 'USA'
}
};
const city = userWithAddress && userWithAddress.address && userWithAddress.address.city;
console.log(city); // 'Metropolis'
// Mis siis, kui 'user' ise on null või undefined?
const nullUser = null;
const streetFromNullUser = nullUser && nullUser.address && nullUser.address.street;
console.log(streetFromNullUser); // null (turvaline, kuid paljusõnaline)
Kuigi see lähenemisviis hoiab ära vigu, on see:
- Paljusõnaline: Iga pesastamise tase nõuab korduvat kontrolli.
- Ăśleliigne: Muutuja nime korratakse mitu korda.
- Potentsiaalselt eksitav: See võib tagastada mis tahes väära väärtuse (nagu
0,'',false), kui see ahelas esineb, mis ei pruugi olla kavandatud käitumine, kui kontrollitakse spetsiifiliseltnullvõiundefinedväärtust.
2. Pesastatud if-laused
Teine levinud muster hõlmas olemasolu selgesõnalist kontrollimist igal tasandil.
let country = 'Unknown';
if (userWithAddress) {
if (userWithAddress.address) {
if (userWithAddress.address.country) {
country = userWithAddress.address.country;
}
}
}
console.log(country); // 'USA'
// Kasutajaobjektiga, millel puudub aadress:
const anotherUser = {
id: 'u125',
name: 'Charlie Brown'
};
let postcode = 'N/A';
if (anotherUser && anotherUser.address && anotherUser.address.postcode) {
postcode = anotherUser.address.postcode;
}
console.log(postcode); // 'N/A'
See lähenemisviis, kuigi selgesõnaline, viib sügavalt taandatud ja raskesti loetava koodini, mida tuntakse omadustele juurdepääsu puhul tavaliselt kui "callback hell" või "püramiidi hukatus". See skaleerub halvasti keerukamate andmestruktuuridega.
Need traditsioonilised meetodid rõhutavad vajadust elegantsema ja lühema lahenduse järele, et turvaliselt navigeerida potentsiaalselt puuduvate andmete vahel. Siin astubki mängu valikuline aheldamine kui kaasaegse JavaScripti arenduse mängumuutja.
Tutvustame valikulist aheldamist (?.): teie turvaline navigaator
Valikuline aheldamine on fantastiline lisandus JavaScriptile, mis võimaldab teil lugeda sügaval seotud objektide ahelas asuva omaduse väärtust, ilma et peaksite selgesõnaliselt kontrollima, kas iga viide ahelas on kehtiv. Operaator ?. töötab sarnaselt . aheldamisoperaatoriga, kuid selle asemel, et visata viga, kui viide on null või undefined, see "lühistab" ja tagastab undefined.
Kuidas valikuline aheldamine töötab
Kui kasutate valikulise aheldamise operaatorit (?.) avaldises nagu obj?.prop, hindab JavaScripti mootor esmalt obj. Kui obj ei ole null ega undefined, siis jätkab see prop-le juurdepääsuga. Kui obj *on* null või undefined, siis kogu avaldis hindub kohe undefined-ks ja viga ei visata.
See käitumine laieneb mitmele pesastamise tasemele ja töötab omaduste, meetodite ja massiivi elementide puhul.
Süntaks ja praktilised näited
1. Valikuline juurdepääs omadustele
See on kõige levinum kasutusjuhtum, mis võimaldab teil turvaliselt juurde pääseda pesastatud objekti omadustele.
const userProfile = {
id: 'p001',
name: 'Maria Rodriguez',
location: {
city: 'Barcelona',
country: 'Spain'
},
preferences: null // eelistuste objekt on null
};
const companyData = {
name: 'Global Corp',
address: {
street: '456 Tech Ave',
city: 'Singapore',
postalCode: '123456'
},
contactInfo: undefined // contactInfo on undefined
};
// Turvaline juurdepääs pesastatud omadustele
console.log(userProfile?.location?.city); // 'Barcelona'
console.log(userProfile?.preferences?.theme); // undefined (sest preferences on null)
console.log(companyData?.contactInfo?.email); // undefined (sest contactInfo on undefined)
console.log(userProfile?.nonExistentProperty?.anotherOne); // undefined
// Ilma valikulise aheldamiseta viskaksid need vead:
// console.log(userProfile.preferences.theme); // TypeError: Cannot read properties of null (reading 'theme')
// console.log(companyData.contactInfo.email); // TypeError: Cannot read properties of undefined (reading 'email')
2. Valikulised meetodite kutsed
Võite kasutada valikulist aheldamist ka meetodi kutsumisel, mis ei pruugi objektil eksisteerida. Kui meetod on null või undefined, hindub avaldis undefined-ks ja meetodit ei kutsuta.
const analyticsService = {
trackEvent: (name, data) => console.log(`Tracking event: ${name} with data:`, data)
};
const userService = {}; // Siin pole 'log' meetodit
analyticsService.trackEvent?.('user_login', { userId: 'u123' });
// Oodatav väljund: Tracking event: user_login with data: { userId: 'u123' }
userService.log?.('User updated', { id: 'u124' });
// Oodatav väljund: Midagi ei juhtu, viga ei visata. Avaldis tagastab undefined.
See on uskumatult kasulik tegelemisel valikuliste tagasikutsete, pistikprogrammide või funktsioonilülititega, kus funktsioon võib tingimuslikult eksisteerida.
3. Valikuline juurdepääs massiivile/sulgude notatsioonile
Valikuline aheldamine töötab ka sulgude notatsiooniga, et pääseda juurde massiivi elementidele või erimärkidega omadustele.
const userActivities = {
events: ['login', 'logout', 'view_profile'],
purchases: []
};
const globalSettings = {
'app-name': 'My App',
'version-info': {
'latest-build': '1.0.0'
}
};
console.log(userActivities?.events?.[0]); // 'login'
console.log(userActivities?.purchases?.[0]); // undefined (tĂĽhi massiiv, seega element indeksil 0 on undefined)
console.log(userActivities?.preferences?.[0]); // undefined (preferences pole defineeritud)
// Juurdepääs sidekriipsudega omadustele kasutades sulgude notatsiooni
console.log(globalSettings?.['app-name']); // 'My App'
console.log(globalSettings?.['version-info']?.['latest-build']); // '1.0.0'
console.log(globalSettings?.['config']?.['env']); // undefined
Valikulise aheldamise peamised eelised
-
Loetavus ja lühidus: See vähendab dramaatiliselt kaitsvate kontrollide jaoks vajaliku koodi hulka. Teie kood muutub palju puhtamaks ja lihtsamini mõistetavaks ühe pilguga.
// Enne const regionCode = (user && user.address && user.address.country && user.address.country.region) ? user.address.country.region : 'N/A'; // Pärast const regionCode = user?.address?.country?.region ?? 'N/A'; // (kombineerides nullilähedase ühendamisega vaikeväärtuse saamiseks) -
Vigade ennetamine: Kõrvaldab käitusaja
TypeErrorvead, mis on põhjustatud katsest pääseda juurdenullvõiundefinedväärtuste omadustele. See viib stabiilsemate rakendusteni. - Parem arendajakogemus: Arendajad saavad keskenduda rohkem äriloogikale kui kaitsvale programmeerimisele, mis viib kiiremate arendustsüklite ja vähemate vigadeni.
- Elegantne andmete käsitlemine: See võimaldab rakendustel elegantselt käsitleda stsenaariume, kus andmed võivad olla osaliselt kättesaadavad või struktureeritud teisiti kui oodatud, mis on tavaline väliste API-de või kasutajate loodud sisu puhul erinevatest rahvusvahelistest allikatest. Näiteks võivad kasutaja kontaktandmed mõnes piirkonnas olla valikulised, kuid teistes kohustuslikud.
Millal kasutada ja millal mitte kasutada valikulist aheldamist
Kuigi valikuline aheldamine on uskumatult kasulik, on oluline mõista selle sobivat rakendamist:
Kasutage valikulist aheldamist, kui:
-
Omadus või meetod on tõeliselt valikuline: See tähendab, et on aktsepteeritav, et vahepealne viide on
nullvõiundefinedja teie rakendus saab ilma selleta jätkata, kasutades võimalusel vaikeväärtust.const dashboardConfig = { theme: 'dark', modules: [ { name: 'Analytics', enabled: true }, { name: 'Reports', enabled: false } ] }; // Kui 'notifications' moodul on valikuline const notificationsEnabled = dashboardConfig.modules.find(m => m.name === 'Notifications')?.enabled; console.log(notificationsEnabled); // undefined, kui ei leita - Tegelete API vastustega, millel võib olla ebajärjekindel struktuur: Erinevate lõpp-punktide või API versioonide andmed võivad mõnikord jätta teatud väljad välja. Valikuline aheldamine aitab teil selliseid andmeid ohutult tarbida.
-
Pääsete juurde dünaamiliselt genereeritud või kasutaja esitatud objektide omadustele: Kui te ei saa garanteerida objekti kuju, pakub
?.turvavõrku.
Vältige valikulist aheldamist, kui:
-
Omadus või meetod on kriitiline ja *peab* eksisteerima: Kui omaduse puudumine viitab tõsisele veale või kehtetule olekule, peaksite lubama
TypeErrorvea viskamist, et saaksite tuvastada ja parandada algpõhjuse.?.kasutamine siin varjaks probleemi.// Kui 'userId' on absoluutselt kriitiline iga kasutajaobjekti jaoks const user = { name: 'Jane' }; // Puudub 'id' // TypeError siin viitaks tõsisele andmete terviklikkuse probleemile // console.log(user?.id); // Tagastab undefined, varjates potentsiaalselt viga // Eelistage lasta sel veaks minna või kontrollige selgesõnaliselt: if (!user.id) { throw new Error('User ID is missing and required!'); } -
Selgus kannatab liigse aheldamise tõttu: Kuigi lühike, võib väga pikk valikuline ahel (nt
obj?.prop1?.prop2?.prop3?.prop4?.prop5) muutuda raskesti loetavaks. Mõnikord võib selle lahtivõtmine või andmete ümberstruktureerimine olla parem. -
Peate eristama
null/undefinedja teisi vääraid väärtusi (0,'',false): Valikuline aheldamine kontrollib ainultnullvõiundefinedväärtusi. Kui peate teisi vääraid väärtusi erinevalt käsitlema, võite vajada selgesõnalisemat kontrolli või kombineerida seda nullilähedase ühendamisega, mida käsitleme järgmisena.
Nullilähedase ühendamise (??) mõistmine: täpsed vaikeväärtused
Kuigi valikuline aheldamine aitab teil turvaliselt juurde pääseda omadustele, mis *võivad* mitte eksisteerida, aitab nullilähedane ühendamine (??) teil pakkuda vaikeväärtust spetsiifiliselt siis, kui väärtus on null või undefined. Seda kasutatakse sageli koos valikulise aheldamisega, kuid sellel on eristuv käitumine ja see lahendab erineva probleemi kui traditsiooniline loogiline VÕI (||) operaator.
Kuidas nullilähedane ühendamine töötab
Nullilähedase ühendamise operaator (??) tagastab oma parempoolse operandi, kui selle vasakpoolne operand on null või undefined, ja vastasel juhul tagastab oma vasakpoolse operandi. See on oluline eristus ||-st, kuna see ei käsitle teisi vääraid väärtusi (nagu 0, '', false) nullilähedastena.
Eristus loogilisest VÕI-st (||)
See on võib-olla kõige olulisem kontseptsioon, mida ?? mõistmisel haarata.
-
Loogiline VÕI (
||): Tagastab parempoolse operandi, kui vasakpoolne operand on mis tahes väär väärtus (false,0,'',null,undefined,NaN). -
Nullilähedane ühendamine (
??): Tagastab parempoolse operandi ainult siis, kui vasakpoolne operand on spetsiifiliseltnullvõiundefined.
Vaatame näiteid selle erinevuse selgitamiseks:
// Näide 1: 'null' või 'undefined' väärtusega
const nullValue = null;
const undefinedValue = undefined;
const defaultValue = 'Default Value';
console.log(nullValue || defaultValue); // 'Default Value'
console.log(nullValue ?? defaultValue); // 'Default Value'
console.log(undefinedValue || defaultValue); // 'Default Value'
console.log(undefinedValue ?? defaultValue); // 'Default Value'
// --- Käitumine erineb siin ---
// Näide 2: 'false' väärtusega
const falseValue = false;
console.log(falseValue || defaultValue); // 'Default Value' (|| käsitleb false'i väärana)
console.log(falseValue ?? defaultValue); // false (?? käsitleb false'i kehtiva väärtusena)
// Näide 3: '0' väärtusega
const zeroValue = 0;
console.log(zeroValue || defaultValue); // 'Default Value' (|| käsitleb 0 väärana)
console.log(zeroValue ?? defaultValue); // 0 (?? käsitleb 0 kehtiva väärtusena)
// Näide 4: tühja stringiga ''
const emptyString = '';
console.log(emptyString || defaultValue); // 'Default Value' (|| käsitleb '' väärana)
console.log(emptyString ?? defaultValue); // '' (?? käsitleb '' kehtiva väärtusena)
// Näide 5: NaN-ga
const nanValue = NaN;
console.log(nanValue || defaultValue); // 'Default Value' (|| käsitleb NaN-i väärana)
console.log(nanValue ?? defaultValue); // NaN (?? käsitleb NaN-i kehtiva väärtusena)
Põhiline järeldus on see, et ?? pakub palju täpsemat kontrolli vaikeväärtuste üle. Kui 0, false või tühi string '' on teie rakenduse loogikas kehtivad ja tähendusrikkad väärtused, siis peaksite vaikeväärtuste määramiseks kasutama operaatorit ??, kuna || asendaks need valesti.
Süntaks ja praktilised näited
1. Vaikekonfiguratsiooni väärtuste määramine
See on ideaalne kasutusjuhtum nullilähedase ühendamise jaoks, tagades, et kehtivad selgesõnalised seaded (isegi kui need on väärad) säilitatakse, samas kui tõeliselt puuduvad seaded saavad vaikeväärtuse.
const userSettings = {
theme: 'light',
fontSize: 14,
enableNotifications: false, // Kasutaja on selgesõnaliselt määranud false
animationSpeed: null // animationSpeed on selgesõnaliselt määratud null (võib-olla vaikeväärtuse pärimiseks)
};
const defaultSettings = {
theme: 'dark',
fontSize: 16,
enableNotifications: true,
animationSpeed: 300
};
const currentTheme = userSettings.theme ?? defaultSettings.theme;
console.log(`Current Theme: ${currentTheme}`); // 'light'
const currentFontSize = userSettings.fontSize ?? defaultSettings.fontSize;
console.log(`Current Font Size: ${currentFontSize}`); // 14 (mitte 16, sest 0 on kehtiv number)
const notificationsEnabled = userSettings.enableNotifications ?? defaultSettings.enableNotifications;
console.log(`Notifications Enabled: ${notificationsEnabled}`); // false (mitte true, sest false on kehtiv boolean)
const animationDuration = userSettings.animationSpeed ?? defaultSettings.animationSpeed;
console.log(`Animation Duration: ${animationDuration}`); // 300 (sest animationSpeed oli null)
const language = userSettings.language ?? 'en-US'; // language pole defineeritud
console.log(`Selected Language: ${language}`); // 'en-US'
2. Valikuliste API parameetrite või kasutajasisendi käsitlemine
API päringute koostamisel või kasutajavormide esitamiste töötlemisel võivad teatud väljad olla valikulised. ?? aitab teil määrata mõistlikke vaikeväärtusi, ilma et kirjutaksite üle õigustatud null- või väärväärtusi.
function searchProducts(query, options) {
const resultsPerPage = options?.limit ?? 20; // Vaikimisi 20, kui limiit on null/undefined
const minPrice = options?.minPrice ?? 0; // Vaikimisi 0, lubades tegelikku 0 kehtiva miinimumhinnana
const sortBy = options?.sortBy ?? 'relevance';
console.log(`Searching for: '${query}'`);
console.log(` Results per page: ${resultsPerPage}`);
console.log(` Minimum price: ${minPrice}`);
console.log(` Sort by: ${sortBy}`);
}
searchProducts('laptops', { limit: 10, minPrice: 500 });
// Oodatav:
// Searching for: 'laptops'
// Results per page: 10
// Minimum price: 500
// Sort by: relevance
searchProducts('keyboards', { minPrice: 0, sortBy: null }); // minPrice on 0, sortBy on null
// Oodatav:
// Searching for: 'keyboards'
// Results per page: 20
// Minimum price: 0
// Sort by: relevance (sest sortBy oli null)
searchProducts('monitors', {}); // Valikuid pole antud
// Oodatav:
// Searching for: 'monitors'
// Results per page: 20
// Minimum price: 0
// Sort by: relevance
Nullilähedase ühendamise peamised eelised
-
Täpsus vaikeväärtustes: Tagab, et ainult tõeliselt puuduvad väärtused (
nullvõiundefined) asendatakse vaikeväärtusega, säilitades kehtivad väärad väärtused nagu0,''võifalse. -
Selgem kavatsus: Väljendab selgelt, et soovite pakkuda varuvarianti ainult
nullvõiundefinedväärtuste jaoks, muutes teie koodi loogika läbipaistvamaks. -
Vastupidavus: Hoiab ära soovimatuid kõrvalmõjusid, kus õigustatud
0võifalseoleks võinud asendada vaikeväärtusega, kui kasutada||. -
Globaalne rakendus: See täpsus on eluliselt tähtis rakendustele, mis tegelevad erinevate andmetüüpidega, näiteks finantsrakendused, kus
0on oluline väärtus, või rahvusvahelistumise seaded, kus tühi string võib esindada tahtlikku valikut.
Võimas paar: valikuline aheldamine ja nullilähedane ühendamine koos
Kuigi iseseisvalt võimsad, säravad valikuline aheldamine ja nullilähedane ühendamine tõeliselt, kui neid kasutatakse kombinatsioonis. See sünergia võimaldab erakordselt vastupidavat ja lühikest andmetele juurdepääsu täpse vaikekäsitlusega. Saate turvaliselt süveneda potentsiaalselt puuduvatesse objektistruktuuridesse ja seejärel, kui lõplik väärtus on null või undefined, pakkuda kohe tähendusrikast varuvarianti.
Sünergilised näited
1. Juurdepääs pesastatud omadustele vaikevaruvariandiga
See on kõige levinum ja mõjukam kombineeritud kasutusjuhtum.
const userData = {
id: 'user-007',
name: 'James Bond',
contactDetails: {
email: 'james.bond@mi6.gov.uk',
phone: '007-007-0070'
},
// eelistused puuduvad
address: {
street: 'Whitehall St',
city: 'London'
// sihtnumber puudub
}
};
const clientData = {
id: 'client-101',
name: 'Global Ventures Inc.',
location: {
city: 'New York'
}
};
const guestData = {
id: 'guest-999'
};
// Turvaliselt kasutaja eelistatud keele saamine, vaikimisi 'en-GB'
const userLang = userData?.preferences?.language ?? 'en-GB';
console.log(`User Language: ${userLang}`); // 'en-GB'
// Kliendi riigi saamine, vaikimisi 'Unknown'
const clientCountry = clientData?.location?.country ?? 'Unknown';
console.log(`Client Country: ${clientCountry}`); // 'Unknown'
// KĂĽlalise kuvatava nime saamine, vaikimisi 'Guest'
const guestDisplayName = guestData?.displayName ?? 'Guest';
console.log(`Guest Display Name: ${guestDisplayName}`); // 'Guest'
// Kasutaja sihtnumbri saamine, vaikimisi 'N/A'
const userPostcode = userData?.address?.postcode ?? 'N/A';
console.log(`User Postcode: ${userPostcode}`); // 'N/A'
// Mis siis, kui selgesõnaliselt tühi string on kehtiv?
const profileWithEmptyBio = {
username: 'coder',
info: { bio: '' }
};
const profileWithNullBio = {
username: 'developer',
info: { bio: null }
};
const bio1 = profileWithEmptyBio?.info?.bio ?? 'No bio provided';
console.log(`Bio 1: '${bio1}'`); // Bio 1: '' (tühi string säilitatakse)
const bio2 = profileWithNullBio?.info?.bio ?? 'No bio provided';
console.log(`Bio 2: '${bio2}'`); // Bio 2: 'No bio provided' (null asendatakse)
2. Tingimuslik meetodite kutsumine varutegevusega
Saate seda kombinatsiooni kasutada meetodi täitmiseks, kui see eksisteerib, vastasel juhul sooritage vaike-tegevus või logige teade.
const logger = {
log: (message) => console.log(`[INFO] ${message}`)
};
const analytics = {}; // Puudub 'track' meetod
const systemEvent = 'application_start';
// Proovi sündmust jälgida, vastasel juhul lihtsalt logi see
analytics.track?.(systemEvent, { origin: 'bootstrap' }) ?? logger.log(`Fallback: Could not track event '${systemEvent}'`);
// Oodatav: [INFO] Fallback: Could not track event 'application_start'
const anotherLogger = {
warn: (msg) => console.warn(`[WARN] ${msg}`),
log: (msg) => console.log(`[LOG] ${msg}`)
};
anotherLogger.track?.('test') ?? anotherLogger.warn('Track method not available.');
// Oodatav: [WARN] Track method not available.
3. Rahvusvahelistumise (i18n) andmete käsitlemine
Globaalsetes rakendustes võivad i18n andmestruktuurid olla keerulised ja teatud tõlked võivad konkreetsete lokaatide jaoks puududa. See kombinatsioon tagab vastupidava varumehhanismi.
const translations = {
'en-US': {
greeting: 'Hello',
messages: {
welcome: 'Welcome!',
error: 'An error occurred.'
}
},
'es-ES': {
greeting: 'Hola',
messages: {
welcome: '¡Bienvenido!',
loading: 'Cargando...'
}
}
};
function getTranslation(locale, keyPath, defaultValue) {
// Jaota keyPath omaduste massiiviks
const keys = keyPath.split('.');
// Dünaamiline juurdepääs pesastatud omadustele kasutades valikulist aheldamist
let result = translations[locale];
for (const key of keys) {
result = result?.[key];
}
// Paki vaikeväärtus, kui tõlge on null või undefined
return result ?? defaultValue;
}
console.log(getTranslation('en-US', 'messages.welcome', 'Fallback Welcome')); // 'Welcome!'
console.log(getTranslation('es-ES', 'messages.welcome', 'Fallback Welcome')); // '¡Bienvenido!'
console.log(getTranslation('es-ES', 'messages.error', 'Fallback Error')); // 'Fallback Error' (error puudub es-ES-is)
console.log(getTranslation('fr-FR', 'greeting', 'Bonjour')); // 'Bonjour' (fr-FR lokaat puudub täielikult)
See näide demonstreerib kaunilt, kuidas ?. võimaldab turvalist navigeerimist läbi potentsiaalselt olematute lokaadiobjektide ja pesastatud sõnumivõtmete, samas kui ?? tagab, et kui konkreetne tõlge puudub, pakutakse undefined asemel mõistlikku vaikeväärtust.
Täiustatud kasutusjuhtumid ja kaalutlused
1. Lühistav käitumine
On oluline meeles pidada, et valikuline aheldamine lühistab. See tähendab, et kui ahelas olev operand hindub null või undefined väärtuseks, siis ülejäänud avaldist ei hinnata. See võib olla kasulik jõudluse seisukohalt ja kõrvalmõjude vältimiseks.
let count = 0;
const user = {
name: 'Anna',
getAddress: () => {
count++;
console.log('Fetching address...');
return { city: 'Paris' };
}
};
const admin = null;
// user eksisteerib, getAddress kutsutakse
console.log(user?.getAddress()?.city); // Väljund: Fetching address..., seejärel 'Paris'
console.log(count); // 1
// admin on null, getAddress EI kutsuta
console.log(admin?.getAddress()?.city); // Väljund: undefined
console.log(count); // Ikka 1 (getAddress ei käivitatud)
2. Valikuline aheldamine destruktureerimisega (ettevaatlik rakendamine)
Kuigi te ei saa otse kasutada valikulist aheldamist destruktureerivas *omastamises* nagu const { user?.profile } = data;, saate seda kasutada muutujate defineerimisel objektist ja seejärel varuvariantide pakkumisel või destruktureerides pärast omadusele turvalist juurdepääsu.
const apiResponse = {
success: true,
payload: {
data: {
user: {
id: 'u456',
name: 'David',
email: 'david@example.com'
}
}
}
};
const emptyResponse = {
success: false
};
// Sügavalt pesastatud andmete ekstraheerimine vaikeväärtusega
const userId = apiResponse?.payload?.data?.user?.id ?? 'guest';
const userName = apiResponse?.payload?.data?.user?.name ?? 'Anonymous';
console.log(`User ID: ${userId}, Name: ${userName}`); // User ID: u456, Name: David
const guestId = emptyResponse?.payload?.data?.user?.id ?? 'guest';
const guestName = emptyResponse?.payload?.data?.user?.name ?? 'Anonymous';
console.log(`Guest ID: ${guestId}, Name: ${guestName}`); // Guest ID: guest, Name: Anonymous
// Levinud muster on esmalt turvaliselt objektile juurde pääseda, seejärel destruktureerida, kui see eksisteerib:
const { user: userDataFromResponse } = apiResponse.payload.data;
const { id = 'default-id', name = 'Default Name' } = userDataFromResponse ?? {};
console.log(`Destructured ID: ${id}, Name: ${name}`); // Destructured ID: u456, Name: David
// TĂĽhja vastuse puhul:
const { user: userDataFromEmptyResponse } = emptyResponse.payload?.data ?? {}; // Kasuta valikulist aheldamist payload.data jaoks, seejärel ?? {} user jaoks
const { id: emptyId = 'default-id', name: emptyName = 'Default Name' } = userDataFromEmptyResponse ?? {};
console.log(`Destructured Empty ID: ${emptyId}, Name: ${emptyName}`); // Destructured Empty ID: default-id, Name: Default Name
3. Operaatorite eesõigus ja grupeerimine
Valikulisel aheldamisel (?.) on kõrgem eesõigus kui nullilähedasel ühendamisel (??). See tähendab, et a?.b ?? c tõlgendatakse kui (a?.b) ?? c, mis on tavaliselt soovitud käitumine. Tavaliselt ei vaja te selle kombinatsiooni jaoks lisasulgusid.
const config = {
value: null
};
// Hindab korrektselt (config?.value) ?? 'default'
const result = config?.value ?? 'default';
console.log(result); // 'default'
// Kui väärtus oli 0:
const configWithZero = {
value: 0
};
const resultZero = configWithZero?.value ?? 'default';
console.log(resultZero); // 0 (kuna 0 ei ole nullilähedane)
4. Integreerimine tĂĽĂĽbikontrolliga (nt TypeScript)
TypeScripti kasutavatele arendajatele on valikulise aheldamise ja nullilähedase ühendamise operaatorid täielikult toetatud ja suurendavad tüübiohutust. TypeScript saab neid operaatoreid kasutada tüüpide korrektseks järeldamiseks, vähendades vajadust selgesõnaliste null-kontrollide järele teatud stsenaariumides ja muutes tüübisüsteemi veelgi võimsamaks.
// Näide TypeScriptis (kontseptuaalne, mitte käivitatav JS)
interface User {
id: string;
name: string;
email?: string; // email on valikuline
address?: {
street: string;
city: string;
zipCode?: string; // zipCode on valikuline
};
}
function getUserEmail(user: User): string {
// TypeScript mõistab, et user.email võib olla undefined, ja käsitleb seda ?? abil
return user.email ?? 'No email provided';
}
function getUserZipCode(user: User): string {
// TypeScript mõistab, et address ja zipCode on valikulised
return user.address?.zipCode ?? 'N/A';
}
const user1: User = { id: '1', name: 'John Doe', email: 'john@example.com', address: { street: 'Main', city: 'Town' } };
const user2: User = { id: '2', name: 'Jane Doe' }; // Puudub email või aadress
console.log(getUserEmail(user1)); // 'john@example.com'
console.log(getUserEmail(user2)); // 'No email provided'
console.log(getUserZipCode(user1)); // 'N/A' (zipCode puudub)
console.log(getUserZipCode(user2)); // 'N/A' (address puudub)
See integratsioon sujuvdab arendust, kuna kompilaator aitab teil tagada, et kõik valikulised ja nullilähedased teed on korrektselt käsitletud, vähendades veelgi käitusaja vigu.
Parimad praktikad ja globaalne perspektiiv
Valikulise aheldamise ja nullilähedase ühendamise tõhus kasutuselevõtt hõlmab enamat kui lihtsalt nende süntaksi mõistmist; see nõuab strateegilist lähenemist andmete käsitlemisele ja koodi disainile, eriti globaalsele publikule suunatud rakenduste puhul.
1. Tunne oma andmeid
Püüdke alati mõista oma andmete potentsiaalseid struktuure, eriti välistest allikatest. Kuigi ?. ja ?? pakuvad turvalisust, ei asenda need vajadust selgete andmelepingute või API dokumentatsiooni järele. Kasutage neid, kui väli on *eeldatavalt* valikuline või võib puududa, mitte kui üldist lahendust tundmatutele andmeskeemidele.
2. Tasakaalusta lĂĽhidust ja loetavust
Kuigi need operaatorid muudavad koodi lühemaks, võivad liiga pikad ahelad siiski muutuda raskesti loetavaks. Kaaluge väga sügavate juurdepääsuteede lahtivõtmist või vahepealsete muutujate loomist, kui see parandab selgust.
// Potentsiaalselt vähem loetav:
const userCity = clientRequest?.customer?.billing?.primaryAddress?.location?.city?.toUpperCase() ?? 'UNKNOWN';
// Loetavam jaotus:
const primaryAddress = clientRequest?.customer?.billing?.primaryAddress;
const userCity = primaryAddress?.location?.city?.toUpperCase() ?? 'UNKNOWN';
3. Erista 'puuduvat' ja 'selgesõnaliselt tühja/nulli'
Siin särab ?? tõeliselt. Rahvusvaheliste vormide või andmesisestuse puhul võib kasutaja selgesõnaliselt sisestada '0' koguse jaoks, 'false' boolean seade jaoks või tühja stringi '' valikulise kommentaari jaoks. Need on kehtivad sisendid ja neid ei tohiks asendada vaikeväärtusega. ?? tagab selle täpsuse, erinevalt ||-st, mis käsitleks neid vaikeväärtuse käivitajatena.
4. Veakäsitlus: endiselt oluline
Valikuline aheldamine hoiab ära TypeError vead null/undefined juurdepääsu puhul, kuid see ei hoia ära muud tüüpi vigu (nt võrguvead, kehtetud funktsiooniargumendid, loogikavead). Vastupidav rakendus nõuab endiselt põhjalikke veakäsitlusstrateegiaid, nagu try...catch plokid muude potentsiaalsete probleemide jaoks.
5. Arvesta brauseri/keskkonna toega
Valikuline aheldamine ja nullilähedane ühendamine on kaasaegsed JavaScripti funktsioonid (ES2020). Kuigi need on laialdaselt toetatud kaasaegsetes brauserites ja Node.js versioonides, peate vanemaid keskkondi sihtides võib-olla oma koodi transpileerima, kasutades tööriistu nagu Babel. Kontrollige alati oma sihtrühma brauseristatistikat, et tagada ühilduvus või planeerida transpileerimist.
6. Globaalne perspektiiv vaikeväärtustele
Vaikeväärtuste pakkumisel arvestage oma globaalse publikuga. Näiteks:
- Kuupäevad ja kellaajad: Konkreetsele ajavööndile või vormingule vaikeväärtuse määramisel tuleks arvestada kasutaja asukohaga.
- Valuutad: Vaikevaluuta (nt USD) ei pruugi olla kõigile kasutajatele sobiv.
- Keel: Pakkuge alati mõistlikku varukeelt (nt inglise keel), kui konkreetse lokaadi tõlge puudub.
- Mõõtühikud: Vaikeväärtuseks 'meetriline' või 'impeeriumi' määramine peaks olema kontekstiteadlik.
Need operaatorid muudavad selliste kontekstiteadlike vaikeväärtuste elegantse rakendamise lihtsamaks.
Kokkuvõte
JavaScripti valikuline aheldamine (?.) ja nullilähedane ühendamine (??) on iga kaasaegse arendaja jaoks asendamatud tööriistad. Need pakuvad elegantseid, lühikesi ja vastupidavaid lahendusi levinud probleemidele, mis on seotud potentsiaalselt puuduvate või defineerimata andmete käsitlemisega keerulistes objektistruktuurides.
Valikulise aheldamise abil saate turvaliselt navigeerida sügavates omaduste teedes ja kutsuda meetodeid ilma rakendust kokku jooksutavate TypeError-ide hirmuta. Nullilähedase ühendamise integreerimisega saate täpse kontrolli vaikeväärtuste üle, tagades, et asendatakse ainult tõeliselt null või undefined väärtused, samas kui õigustatud väärad väärtused nagu 0 või false säilitatakse.
Koos parandab see "võimas paar" oluliselt koodi loetavust, vähendab korduvat koodi ja viib vastupidavamate rakendusteni, mis käsitlevad elegantselt reaalmaailma andmete ettearvamatut olemust erinevates globaalsetes keskkondades. Nende funktsioonide omaksvõtmine on selge samm puhtama, hooldatavama ja väga professionaalse JavaScripti koodi kirjutamise suunas. Alustage nende integreerimist oma projektidesse juba täna ja kogege erinevust, mida need toovad tõeliselt vastupidavate rakenduste ehitamisel kasutajatele üle maailma!