Síðustu ár hafa sýnt okkur að vefþróun er að breytast. Þegar mörg eiginleikar og API-skjöl voru bætt við vafrana þurftum við að nota þau á réttan hátt. Málinu sem við skuldum þessa heiður var JavaScript.
Í upphafi voru forritararnir ekki sannfærðir um hönnunina og höfðu að mestu neikvæðar skoðanir á meðan þeir notuðu þennan kóða. Með tímanum kom í ljós að þetta forritunarmál hefur mikla möguleika, og síðar ECMAScript-staðlar gera suma hluta vélrænnar framkvæmdar mannlegri og einfaldlega betri. Í þessari grein skoðum við nokkra þeirra.
Gerðir gilda í JS
Vel þekkt sannleikur um JavaScript Er að allt hér er hlutur. Í alvöru, allt: fylki, fall, strengir, tölur og jafnvel booleans. Allar tegundir gilda eru táknaðar af hlutum og hafa sínar eigin aðferðir og eiginleika. Hins vegar getum við skipt þeim í tvo flokka: frumstæðar og byggingareiningar. Gildi fyrsta flokksins eru óbreytanleg, sem þýðir að við getum úthlutað breytunni nýju gildi en getum ekki breytt núverandi gildi sjálfu. Sá síðari táknar gildi sem hægt er að breyta, svo þau ætti að túlka sem safn eiginleika sem við getum skipt út fyrir eða einfaldlega kallað aðferðir sem eru hannaðar til þess.
Gildissvið lýstra breyta
Áður en við förum dýpra skulum við útskýra hvað gildissvið merkir. Við getum sagt að gildissvið sé eini svæðið þar sem við getum notað lýstar breytur. Áður en ES6-staðallinn kom gátum við lýst breytum með var-yfirlýsingunni og gefið þeim annað hvort alþjóðlegt eða staðbundið gildissvið. Sá fyrrnefndi er svið sem gerir kleift okkur til að nálgast sumar breytur hvar sem er í forritinu, en sú síðari er eingöngu ætluð sérstöku svæði – aðallega falli.
Frá og með staðlinum ES2015, JavaScript Það eru þrjár leiðir til að lýsa breytum sem eru mismunandi eftir lykilorðum. Sú fyrsta er lýst hér að framan: breytur sem lýst er með var-lykilorðinu eru innan gildissviðs núverandi fallagerðar. ES6-staðallinn leyfði okkur að lýsa breytum á mannlegri hátt – ólíkt var-yfirlýsingum eru breytur sem lýst er með const- og let-yfirlýsingum eingöngu innan gildissviðs blokkarins. Hins vegar, JS meðhöndlar const-yfirlýsinguna nokkuð óvenjulega miðað við aðrar forritunarmál – í stað þess að geyma gildi, geymir það varanlega vísun í gildið. Í stuttu máli getum við breytt eiginleikum hlut sem er lýst með const-yfirlýsingu, en við getum ekki skrifað yfir vísun þessa breytils. Sumir segja að var-valkosturinn í ES6 sé í raun let-yfirlýsing. Nei, það er það ekki, var-yfirlýsingin er það ekki og hún verður sennilega aldrei tekin úr notkun. Góð venja er að forðast notkun var-yfirlýsinga, því þær valda okkur yfirleitt meiri vandræðum. Í staðinn misnotum við const-yfirlýsingar, þar til við þurfum að breyta vísun þeirra – þá ættum við að nota let.
Dæmi um óvænt sviðsferli
Skulum byrja á eftirfarandi kóði:
(() => {
for (var i = 0; i {
console.log(`Gildi "i": ${i}`);
}, 1000);
}
})();
Þegar við skoðum þetta virðist for-lykkjan endurtaka gildi i og, eftir eina sekúndu, skrá gildi hliðarbreytunnar: 1, 2, 3, 4, 5. En svo er ekki. Eins og áður hefur komið fram, var-yfirlýsingin snýst um að halda gildi breytu í gegnum allan líkama fallsins; það þýðir að í annarri, þriðju o.s.frv. endurtekningu verður gildi breytunnar i endurnýjað með næsta gildi. Að lokum lýkur lykkjunni og tímaútgáfurnar sýna okkur eftirfarandi: 5, 5, 5, 5, 5. Besta leiðin til að halda núverandi gildi skrefsins er að nota let-yfirlýsinguna í staðinn:
(() => {
for (let i = 0; i {
console.log(`Gildi "i": ${i}`);
}, 1000);
}
})();
Í dæminu hér að ofan höldum við gildissviði i-breytunnar innan núverandi lykkju; það er eina sviðið þar sem við getum notað þessa breytu og ekkert getur yfirritað hana utan þessa svæðis. Niðurstaðan í þessu tilfelli er eins og búist var við: 1 2 3 4 5. Skoðum hvernig á að takast á við þessa stöðu með var-yfirlýsingu:
(() => {
for (var i = 0; i {
setTimeout(() => {
console.log(`Gildi "j": ${j}`);
}, 1000);
})(i);
}
})();
Þar sem var-yfirlýsingin snýst um að halda gildinu innan fallabloksins, verðum við að kalla á skilgreint fall sem tekur einn rökstuðul – gildi núverandi stöðu endurtekjunnar – og framkvæma svo eitthvað. Ekkert utan yfirlýsta fallsins mun yfirskrifa j-gildið.
Dæmi um rangar væntingar um gildi hluta
Algengasta brotið sem ég tók eftir snýst um að hunsa áhrif uppbyggingar og breyta eiginleikum þeirra sem einnig eru breyttir í öðrum kóðahlutum. Kíktu fljótt:
const DEFAULT_VALUE = {
favoriteBand: 'The Weeknd'
};
const currentValue = DEFAULT_VALUE;
const bandInput = document.querySelector('#favorite-band');
const restoreDefaultButton = document.querySelector('#restore-button');
bandInput.addEventListener('input', () => {
currentValue.favoriteBand = bandInput.value;
}, false);
restoreDefaultButton.addEventListener('click', () => {
currentValue = DEFAULT_VALUE;
}, false);
Frá upphafi: gerum ráð fyrir að við höfum líkan með sjálfgefnum eiginleikum, geymdum sem hlut. Við viljum hafa hnapp sem endurheimtir inntaksgildin í sjálfgefnu gildin. Eftir að hafa fyllt inntakið með nokkrum gildum uppfærum við líkanið. Eftir stund hugsa við að sjálfgefin valkostur hafi einfaldlega verið betri, svo við viljum endurheimta hann. Við smellum á hnappinn… og ekkert gerist. Af hverju? Vegna þess að við hunsuðum mátt vísaðra gilda.
Þessi hluti: const currentValue = DEFAULTVALUE segir JavaScript-inu eftirfarandi: Taktu vísunina í DEFAULT.Notaðu VALUE til að ákvarða gildi og úthluta því í breytuna currentValue. Raunverulega gildið er geymt í minni aðeins einu sinni og báðar breyturnar vísa á það. Að breyta sumum eiginleikum á einum stað þýðir að breyta þeim á öðrum stað. Við höfum nokkrar leiðir til að forðast svona aðstæður. Ein sem uppfyllir þarfir okkar er dreifingaroperatórinn. Láttu okkur laga kóðann okkar:
const DEFAULT_VALUE = {
favoriteBand: 'The Weeknd'
};
const currentValue = { ...DEFAULT_VALUE };
const bandInput = document.querySelector('#favorite-band');
const restoreDefaultButton = document.querySelector('#restore-button');
bandInput.addEventListener('input', () => {
currentValue.favoriteBand = bandInput.value;
}, false);
restoreDefaultButton.addEventListener('click', () => {
currentValue = { ...DEFAULT_VALUE };
}, false);
Í þessu tilfelli virkar útbreiðsluaðgerðin svona: hún tekur öll eiginleika úr hlut og býr til nýjan hlut sem er fylltur þeim. Þökk sé þessu vísa gildin í currentValue og DEFAULT_VALUE ekki lengur á sama stað í minni og allar breytingar sem gerðar eru á öðru þeirra hafa ekki áhrif á hitt.
Ok, spurningin er: snýst þetta allt um að nota töfraspread-reikniritinu? Í þessu tilfelli – já, en módelin okkar kunna að krefjast meiri flækju en þetta dæmi. Ef við notum innfelld hluti, fylki eða aðrar uppbyggingar, mun spread-reiknirit á gildi sem vísað er til á efsta stigi aðeins hafa áhrif á efsta stigið og vísaðu eiginleikarnir munu enn deila sama stað í minni. Það eru mörg úrræði til að takast á við þetta vandamál, allt fer eftir þörfum þínum. Við getum afritað hluti á öllum dýptarstigum eða, í flóknari aðgerðum, notað verkfæri eins og immer sem gerir okkur kleift að skrifa óbreytanlegan kóða nánast sársaukalaust.
Blandið öllu saman
Er hægt að nota blöndu af þekkingu á umfangi og gildistegundum? Auðvitað er það hægt! Skulum búa til eitthvað sem notar bæði:
const useValue = (defaultValue) => {
const value = [...defaultValue];
const setValue = (newValue) => {
value.length = 0; // flókin leið til að tæma fylkið
newValue.forEach((item, index) => {
value[index] = item;
});
// gera eitthvað annað
};
return [value, setValue];
};
const [animals, setAnimals] = useValue(['cat', 'dog']);
console.log(animals); // ['cat', 'dog']
setAnimals(['horse', 'cow']);
console.log(animals); // ['horse', 'cow']);
Skýrum hvernig þessi kóði virkar línu fyrir línu. Jæja, useValue-fallið býr til fylki byggt á defaultValue-rökvísinum; það býr til breytu og annað fall, sem er breytir þess. Þessi breytir tekur nýtt gildi sem er á flókinn hátt beitt núverandi gildi. Í lok fallsins skilar það gildinu og breytinum sem fylkigildi. Næst notum við hið búna fall – skilgreinum `animals` og `setAnimals` sem skilaðar gildi. Notum mótfall þeirra til að athuga hvort fallið hafi áhrif á `animal`-breytuna – já, það virkar!
En bíddu, hvað er eiginlega svo glæsilegt við þennan kóða? Vísunin geymir öll nýju gildin og þú getur sprautað þinni eigin rökfræði inn í þennan breytanda, svo sem sumir API-ar eða hluti vistkerfisins sem knýr gagnaflæði þitt án fyrirhafnar. Þetta flókna mynstur er oft notað í nútímalegri JavaScript-bókasöfnum, þar sem virknilíkanið í forritun gerir okkur kleift að halda kóðanum minna flóknum og auðveldara fyrir aðra forritara að lesa.
Yfirlit
Skilningur á því hvernig tungumálsmekanismi virkar undir vélinni gerir okkur kleift að skrifa meðvitaðri og léttari kóða. Þó að JavaScript sé ekki lággreint forritunarmál og krefjist þess að við höfum einhverja þekkingu á úthlutun og geymslu minni, verðum við samt að fylgjast með óvæntum hegðunum þegar við breytum hlutum. Á hinn bóginn er misnotkun afritanna af gildum ekki alltaf rétt leið og rang notkun hefur fleiri ókosti en kosti. Rétt leið til að skipuleggja gagnaflæðið er að íhuga hvað þú þarft og hvaða mögulegar hindranir þú gætir mætt þegar þú innleiðir lógík forritsins.
Lesa meira: