RSS

Spotkanie Koła naukowego FullStack #3: Nowości w ES6

Liczba odsłon: 73

Język ECMAScript, któ­re­go jed­ną z wer­sji jest uży­wa­ny obec­nie Java­Script, pod­le­ga sta­łe­mu roz­wo­jo­wi. Elementy wpro­wa­dzo­ne w szós­tej wer­sji ję­zy­ka, zna­nej ja­ko ECMAScript 2015 lub ES6, moż­na by­ło po­znać w cza­sie spot­ka­nia Koła Naukowego Full­Stack, któ­re od­by­ło się w śro­dę 5 grud­nia w Auli A Wydziału Auto­ma­ty­ki, Elektro­ni­ki i Informa­ty­ki Politech­ni­ki Śląskiej w Gli­wi­cach. Zapraszam do lek­tu­ry re­lac­ji z te­go spot­ka­nia.

Charaktery­stycz­ną ce­chą ję­zy­ka Java­Script jest nie­zmien­ność dia­lek­tu. Ktoś, kto na­uczył się go dwa­dzieś­cia lat te­mu, do dzi­siaj mo­że ko­rzy­stać z tej sa­mej wie­dzy, od cza­su do cza­su po­zna­jąc po­je­dyn­cze no­wo wpro­wa­dzo­ne ele­men­ty ję­zy­ka, głów­nie w za­kre­sie ob­słu­gi DOM lub CSS. Ten brak roz­wo­ju utrud­niał jed­nak im­ple­men­to­wa­nie no­wych tech­nik i osnów pro­gra­mis­tycz­nych oraz ko­rzy­sta­nie z nich. Nic dziw­ne­go, że po­wsta­ły alter­na­tyw­ne ję­zy­ki ta­kie jak Type­Script, za­cho­wu­ją­ce skład­nię ory­gi­na­łu, lecz roz­sze­rza­ją­ce zna­czą­co je­go moż­li­woś­ci a na­wet zmie­nia­ją­ce pod­sta­wo­we za­ło­że­nia. Aby jed­nak ko­rzy­stać z ta­kich roz­wią­zań, trze­ba al­bo użyć kon­te­ne­rów apli­kac­ji umie­ją­cych uru­cha­miać pro­gra­my pi­sa­ne w da­nym ję­zy­ku, al­bo uży­wać trans­la­to­rów tłu­ma­czą­cych tekst źród­ło­wy na stan­dar­do­wy dia­lekt.

Poważnym kro­kiem na­przód jest wpro­wa­dze­nie no­wych wer­sji ję­zy­ka ECMAScript, któ­re­go im­ple­men­tac­ją jest Java­Script. I choć mu­si­my jesz­cze po­cze­kać na peł­ną ob­słu­gę te­go dia­lek­tu w prze­glą­dar­kach WWW, już dzi­siaj war­to przy­go­to­wać się na przy­szłość. Podobnie zresz­tą jak w przy­pad­ku Type­Script, do­stęp­ne są trans­la­to­ry tłu­ma­czą­ce no­wo­czes­ny, ele­ganc­ki kod do po­sta­ci zwyk­łe­go Java­Script.

Istotną, choć nie naj­now­szą wer­sją ECMAScript jest dia­lekt z 2015 ro­ku, na­zy­wa­ny ES6. Można się by­ło z nim za­poz­nać w cza­sie trze­cie­go już spot­ka­nia Koła Naukowego Full­Stack, dzia­ła­ją­ce­go na Wydziale Auto­ma­ty­ki, Elektro­ni­ki i Informa­ty­ki Politech­ni­ki Śląskiej we współ­pra­cy z fir­mą Gorrion. Zadania pod­jął się Tomasz Piela, przez po­nad go­dzi­nę pre­zen­tu­jąc no­we, cha­rak­te­ry­stycz­ne ce­chy ję­zy­ka.

Na wstę­pie zo­sta­ła przed­sta­wio­na kon­cep­cja mo­du­łów. Stanowi ona roz­sze­rze­nie sto­so­wa­ne­go wcześ­niej po­dzia­łu na od­ręb­ne pli­ki skryp­tów .js, po­dob­ne ideą do roz­wią­zań ofe­ro­wa­nych przez bi­blio­te­ki ta­kie jak CommonJS czy AMD. Zamiast wprost okre­ślać wszyst­kie za­leż­noś­ci w pli­ku .html, do­łą­cza­my tyl­ko je­den pod­sta­wo­wy skrypt, a wszyst­kie ko­lej­ne wczy­tu­je­my dyna­micz­nie po­śred­nio, od­wo­łu­jąc się do nich na po­cząt­ku każ­de­go ko­lej­ne­go pli­ku. W ten spo­sób autor stro­ny lub apli­kac­ji nie mu­si znać peł­nej ma­py za­leż­noś­ci wszyst­kich sto­so­wa­nych bi­blio­tek.

Dwie ce­chy zde­cy­do­wa­nie róż­nią mo­du­ły od do­tych­czas sto­so­wa­nych roz­wią­zań. Przede wszyst­kim, ich ob­słu­ga jest wbu­do­wa­na bez­po­śred­nio w plat­for­mę i nie wy­ma­ga sto­so­wa­nia do­dat­ko­wych bi­blio­tek, dzię­ki cze­mu mo­że dzia­łać szyb­ciej i bar­dziej nie­za­wod­nie. Ważniej­sze jest jed­nak peł­ne roz­dzie­le­nie mo­du­łów od sie­bie. Wszystkie sym­bo­le, któ­re zde­fi­niu­je­my w ra­mach jed­ne­go mo­du­łu po­zos­ta­ją dla nie­go pry­wat­ne i nie są wi­docz­ne w po­zo­sta­łych. Jedynie sym­bo­le wy­róż­nio­ne za po­mo­cą sło­wa klu­czo­we­go export są do­stęp­ne do ze­wnętrz­ne­go wy­ko­rzys­ta­nia. Aby z nich sko­rzys­tać, na­le­ży je naj­pierw „za­im­por­to­wać” za po­mo­cą wy­ra­że­nia import. Istnieje też moż­li­wość udos­tęp­nie­nia jed­ne­go nie­naz­wa­ne­go ele­men­tu mo­du­łu (wy­ra­że­nie export de­fault), któ­ry na­stęp­nie jest wczy­ty­wa­ny w miej­scu do­ce­lo­wym z do­wol­nym, okreś­lo­nym po stro­nie mo­du­łu-klien­ta iden­ty­fi­ka­to­rem.

Rewolucją w ję­zy­ku ES6 są kla­sy. Język Java­Script zna­ny jest z te­go, że ja­ko je­den z nie­licz­nych ba­zu­je nie na kon­cep­cji klas, lecz pro­to­ty­pów obiek­tów. Standard ES6 te­go nie zmie­nia, jed­nak wpro­wa­dza sło­dzik skład­nio­wy w po­sta­ci sło­wa klu­czo­we­go class po­zwa­la­ją­ce­go zde­fi­nio­wać kla­sę. Definicja mo­że za­wie­rać kon­struk­tor, me­to­dy sta­tycz­ne i wir­tu­al­ne oraz akce­so­ry pól. Dopuszczal­ne jest rów­nież dzie­dzi­cze­nie po wcześ­niej zde­fi­nio­wa­nych kla­sach. Prelegent za­de­mon­stro­wał no­wą skład­nię na przy­kła­dzie kla­sy Rectangle opi­su­ją­cej pro­sto­kąt, raz za­im­ple­men­to­wa­nej me­cha­niz­ma­mi dia­lek­tu ES5, a raz z wy­ko­rzys­ta­niem no­wej skład­ni.

Możliwo­ści me­cha­niz­mu wpro­wa­dzo­ne­go w ES6 ni­czym nie wy­kra­cza­ją po­za to, co ofe­ru­je ję­zyk Java­Script (ES5). Zapis wy­ko­rzy­stu­ją­cy sło­wo klu­czo­we class jest jed­nak krót­szy, bar­dziej przej­rzy­sty i po­zo­sta­wia znacz­nie mniej miej­sca na błę­dy. Dodatkowo, po­nie­waż róż­ne for­my me­cha­niz­mu klas są pod­sta­wą prak­tycz­nie każ­dej osno­wy pro­gra­mi­stycz­nej (a cza­sem, jak w przy­pad­ku PrototypeJS, sta­no­wią isto­tę bi­blio­te­ki), ze­stan­da­ry­zo­wa­nie me­cha­niz­mu klas za­owo­cu­je więk­szą wy­mien­noś­cią ko­du, lep­szym współ­dzia­ła­niem bi­blio­tek oraz szyb­szym dzia­ła­niem apli­kac­ji.

O ile za­pis klas zo­stał za­po­ży­czo­ny wprost z ję­zy­ka Java, ko­lej­ny no­wy ele­ment – ar­gu­men­ty do­myśl­ne – wzo­ro­wa­ny był praw­do­po­dob­nie na ję­zy­ku C++. Dotych­czas funk­cje przyj­mu­ją­ce zmien­ną licz­bę ar­gu­men­tów mu­sia­ły sa­mo­dziel­nie wy­kry­wać, czy da­ny ar­gu­ment zo­stał po­da­ny i od­po­wied­nio rea­go­wać na je­go brak. W dia­lek­cie ES6 do każ­de­go pa­ra­me­tru moż­na przy­pi­sać ar­gu­ment do­myśl­ny, pod­sta­wia­ny w mo­men­cie bra­ku ar­gu­men­tu w wy­wo­ła­niu funk­cji.

Choć w apli­kac­jach kla­sy web nie­czę­sto ist­nie­je po­trze­ba łą­cze­nia du­żej licz­by frag­men­tów tek­stu w dłuż­szy na­pis, reali­zac­ja ta­kie­go za­da­nia w ję­zy­ku Java­Script wy­ma­ga żmud­ne­go otwie­ra­nia i za­my­ka­nia cu­dzy­sło­wów oraz sto­so­wa­nia ope­ra­to­ra sca­la­nia +. Dialekt ES6 wpro­wa­dza no­we roz­wią­za­nie, po­zwa­la­ją­ce zde­fi­nio­wać szab­lon o po­sta­ci `…`. Szablony res­pek­tu­ją zna­ki przej­ścia do no­we­go wier­sza (co nie­ste­ty mo­że nie współ­grać z wcię­cia­mi tek­stu źród­ło­we­go pro­gra­mu) oraz po­la ${…} po­zwa­la­ją­ce od­wo­ły­wać się do pól oraz funk­cji. Taki za­pis mo­że się przy­dać szcze­gól­nie w przy­pad­ku im­ple­men­to­wa­nia funk­cji diag­nos­tycz­nych ty­pu toString().

Spore moż­li­woś­ci da­ją no­we ope­ra­to­ry eks­pan­sji (ang. spread ope­ra­tor) oraz de­struk­tu­ry­za­cji (ang. de­struc­tu­ring assign­ment). Za po­mo­cą pierw­sze­go moż­na roz­bić tab­li­cę na nie­za­leż­ne ele­men­ty, na przy­kład prze­ka­zy­wa­ne ja­ko ar­gu­men­ty funk­cji ma­ją­cej wie­le pa­ra­met­rów. Z kolei dru­gi po­zwa­la w ra­mach jed­ne­go wy­ra­że­nia przy­pi­sać wy­bra­ne po­zyc­je tab­li­ce do nie­za­leż­nych zmien­nych ska­lar­nych, z po­mi­nię­ciem nie­po­trzeb­nych ele­men­tów. Choć oby­dwa za­pi­sy rów­nież na­le­ży za­kwa­li­fi­ko­wać ja­ko sło­dzik syn­tak­tycz­ny, ich sto­so­wa­nie mo­że skró­cić treść pod­pro­gra­mów prze­kształ­ca­ją­cych ob­szer­ne struk­tu­ry da­nych.

Istotnym tren­dem jest obec­nie prze­no­sze­nie obo­wiąz­ku wy­kry­wa­nia błę­dów w pro­gra­mie na śro­do­wis­ko uru­cho­mie­nio­we. ECMAScript 2015 po­dą­ża tą ścież­ką, wpro­wa­dza­jąc dwa no­we sło­wa klu­czo­we de­fi­niu­ją­ce zmien­ne. Za po­mo­cą let moż­na stwo­rzyć zmien­ną o za­się­gu ogra­ni­czo­nym do po­je­dyn­cze­go blo­ku, zaś const do­dat­ko­wo unie­moż­li­wia póź­niej­szą zmia­nę przy­pi­sa­nej war­toś­ci (lub re­fe­ren­cji). Dzięki ich sto­so­wa­niu moż­na unik­nąć nie­jed­no­znacz­noś­ci sło­wa klu­czo­we­go var, de­fi­niu­ją­ce­go zmien­ne o za­się­gu glo­bal­nym lub ogra­ni­czo­nym do funk­cji, a tak­że przy­pad­ko­we­go dwu­krot­ne­go uży­cia tej sa­mej naz­wy zmien­nej. Jako za­sa­dę na­le­ży przy­jąć pre­fe­ro­wa­nie const po­nad let.

Ukłonem w kie­run­ku pro­gra­mo­wa­nia funk­cyj­ne­go i wy­ra­żeń lamb­dafunk­cje strzał­ko­we. Choć więk­szość pro­gra­mis­tów bę­dzie się mu­sia­ła przy­zwy­czaić do ich spe­cy­ficz­ne­go za­pi­su, po­zwa­la­ją one po­zbyć się z tek­stu źród­ło­we­go pro­gra­mu wszyst­kich tych pros­tych, jed­no­wier­szo­wych funk­cji, tak nisz­czą­cych mi­ster­nie przy­go­to­wa­ną struk­tu­rę wcięć. Dodatkowo, po­nie­waż funk­cje strzał­ko­we nie peł­nią ro­li kon­struk­to­rów obiek­tów, mo­gą być szyb­ciej rea­li­zo­wa­ne oraz nie nad­pi­su­ją re­fe­ren­cji this. Raz na zaw­sze moż­na za­tem zre­zyg­no­wać z roz­po­czy­na­ją­cych każ­dą me­to­dę za­pi­sów var me = this, ty­po­wych dla wie­lu osnów pro­gra­mis­tycz­nych Java­Script.

Nowy stan­dard wpro­wa­dził do ka­no­nu rów­nież in­ny ele­ment po­wszech­nie już sto­so­wa­ny w świe­cie apli­kac­ji Java­Script: wzo­rzec pro­jek­to­wy przy­rze­cze­nia. W dia­lek­cie ES6 kla­sa Promise sta­no­wi stan­dar­do­wy ele­ment ję­zy­ka i nie mu­si być im­ple­men­to­wa­na w każ­dej osno­wie pro­gra­mi­stycz­nej z osob­na. Pełną in­te­grac­ję obiek­tów przy­rze­czeń z ję­zy­kiem moż­na jed­nak uzys­kać do­pie­ro sto­su­jąc dia­lekt ES8, któ­re­go no­we sło­wa klu­czo­we async oraz await po­zwa­la­ją za­pi­sać dzia­ła­nia asyn­chro­nicz­ne w spo­sób cał­ko­wi­cie syn­chro­nicz­ny, a błę­dy zgła­sza­ne przez ope­rac­je asyn­chro­nicz­ne prze­chwy­ty­wać ja­ko sytua­cje wy­jąt­ko­we.

Język ECMAScript 2015 ob­słu­gu­ją wszyst­kie wer­sje prze­glą­da­rek wy­da­ne po­czą­wszy od dru­giej po­ło­wy 2017 ro­ku. Nie moż­na za­tem nie­ste­ty li­czyć, że na­pi­sa­na w nim apli­kac­ja bę­dzie dzia­ła­ła na wszyst­kich kom­pu­te­rach Inter­ne­tu. Szczególnie istot­nym wy­jąt­kiem (choć ma­ło nie­spo­dzie­wa­nym) jest Micro­soft Inter­net Explo­rer. Programi­ści myś­lą­cy o ko­rzy­sta­niu z no­we­go dia­lek­tu mo­gą jed­nak sko­rzys­tać z trans­la­to­rów ta­kich jak Babel, tłu­ma­czą­cych tekst źród­ło­wy ES6 do po­sta­ci w peł­ni zgod­nej z Java­Script. I choć w ten spo­sób tra­ci się część moż­li­wych zy­sków wy­daj­no­ścio­wych, zwięk­szo­na łat­wość ko­rzy­sta­nia z za­awan­so­wa­nych cech ję­zy­ka mo­że mi­mo wszyst­ko pod­nieść ja­kość two­rzo­nych apli­kac­ji.


Wystąpie­nie mia­ło na ce­lu za­syg­na­li­zo­wa­nie naj­waż­niej­szych cech no­we­go dia­lek­tu ję­zy­ka człon­kom Koła Naukowego Full­Stack oraz in­nym za­in­te­re­so­wa­nym. Z te­go po­wo­du by­ło dość krót­kie i treś­ci­we. Prelegent, za­miast wy­czer­pać po­szcze­gól­ne te­ma­ty, po­sta­wił na za­in­te­re­so­wa­nie obec­nych moż­li­woś­cia­mi, ja­kie da­je ES6.

Do spo­rych wad wy­stą­pie­nia za­li­czył­bym nie­do­sta­tecz­ne wcześ­niej­sze prze­tes­to­wa­nie pre­zen­to­wa­nych pro­gra­mów przy­kła­do­wych. W kil­ku przy­pad­kach pre­le­gent me­to­dą prób i błę­dów, cza­sem z po­mo­cą pub­licz­noś­ci, zmie­niał kod aż do mo­men­tu uzys­ka­nia pra­wid­ło­we­go dzia­ła­nia, a raz był zmu­szo­ny cał­ko­wi­cie po­mi­nąć nie dzia­ła­ją­cy przy­kład. Podczas te­go ty­pu wy­stą­pień war­to mieć przy­go­to­wa­ne go­to­we wzor­co­we wy­cin­ki tek­stu źród­ło­we­go pro­gra­mów przy­kła­do­wych: po­zwa­la­ją one zmniej­szyć stres pod­czas pre­zen­to­wa­nia oraz za­po­bie­ga­ją mar­no­wa­niu cza­su oraz roz­bi­ciu ryt­mu pre­zen­tac­ji.

Warto pod­kre­ślić jed­nak do­bre stro­ny, do któ­rych na­le­ży zwar­tość pre­zen­tac­ji, wy­mie­nie­nie wszyst­kich istot­nych no­wych ele­men­tów, po­ka­za­nie krót­kich przy­kła­dów ich uży­cia oraz za­chę­ce­nie uczest­ni­ków do ich sto­so­wa­nia, choć­by za po­mo­cą trans­la­to­rów ta­kich jak Babel.