Cuprins
În tutoriale anterioare, am lucrat cu cursurile, făcând astfel aplicația noastră mai modulară, chiar am văzut în profunzime cum să efectuăm lucrări asincrone folosind CoffeeScript ca limbă, oferindu-ne astfel o gamă mai largă de opțiuni pentru a lucra cu ea.După ce am însușit aceste concepte, este timpul să facem un pas mai departe și să folosim ceea ce știm pentru a scrie un cod mai curat, mai funcțional și, desigur, mai puternic. Este timpul să învățăm cum să devenim utilizatori puternici ai CoffeeScript.
Acum, că știm cum să folosim cursurile în aplicația noastră, este doar o chestiune de timp înainte să avem probleme cu aceasta. context. Când avem funcții simple, este destul de ușor să vedem ce date are această funcție în sfera sa, cunoaște variabile globale, variabile definite în cadrul funcției și orice variabilă care a fost definită în sfera locală atunci când funcția a fost creată.
Dar când metodele sunt legate de obiecte, acest lucru devine puțin mai complicat. Pentru a ilustra acest lucru, să vedem un exemplu în care putem vedea această problemă și apoi vom vedea cum CoffeeScript ne poate ajuta:
clasa Ancoră de ridicare a navei: (doneCallback) -> console.log "Ancoră de ridicare." setVel: (speed) -> console.log "Setarea vitezei la # {speed}" set sail: -> @levantarAncla @ fixVel 70Să presupunem că, conform codului nostru, vrem să pornim imediat, pentru aceasta facem următoarele pentru a invoca funcția noastră:
bot = nou Barco bot.zarpar ()Dacă privim cu atenție și transferăm acest cod în lumea reală, ne putem da seama că ridicarea ancorei nu se întâmplă imediat, trebuie să așteptăm ca ancora să fie ridicată complet pentru a putea naviga. Putem rezolva această problemă adăugând un sună din nou și întrebând dacă a fost finalizată, așa că vom ști cât durează această acțiune și ne vom apela funcția odată terminată, să vedem:
liftAnchor: (doneCallback) -> console.log "Ancora de ridicare". dacă ați făcut apel? setTimeout done Callback, 1000După cum putem vedea, invocăm callback-ul doar dacă acesta există, în acest fel ne asigurăm că acest proces este finalizat și, prin urmare, trebuie să ne modificăm funcția a navigat:
salvați: -> @levantarAncla -> @ fixVel 70Acum ceea ce facem este să invocăm funcția a navigat După ridicarea ancorei, acest lucru ne asigură că nu ne vom mișca până când ancora nu este ridicată complet. Arată destul de bine, vom compila codul nostru și vom include fișierul .js generat într-un HTML pentru a vedea răspunsul de la consolă:
Ceea ce vrem să facem este să ne asigurăm că Este este întotdeauna legat de instanța de bot în interiorul corpului callback-ului și suntem norocoși, de vreme ce CoffeeScript are o funcționalitate pentru cazul respectiv. Pentru aceasta vom declara funcția cu săgeată grasă sau săgeată groasă, în acest fel funcția va avea Este legat de contextul în care a fost declarat, să vedem cum arată codul nostru cu această modificare:
clasa Ancoră de ridicare a navei: (doneCallback) -> console.log "Ancoră de ridicare." dacă ați făcut apel? setTimeout doneCallback, 1000 setVel: (speed) -> console.log "Setting speed to # {speed}" set sail: -> @levantarAncla => @fixVel 70 bot = new Barco bot.zarpar ()Să ne compilăm fișierul și să vedem cum CoffeeScript Realizarea legăturilor cu funcționalitatea săgeții groase:
MemorizareCare este tehnica memoizare este să stochezi valorile unei funcții în loc să le recalculezi de fiecare dată când este apelată funcția. Acum, că știm să folosim clase și obiecte, putem folosi aceste cunoștințe pentru a le aplica în interior CoffeeScript și utilizați tehnica în cauză.
Există multe modalități de a efectua procesul de memoizare, pentru cazul acestui tutorial vom păstra lucrurile simple. Pentru aceasta, ceea ce vom face este că, atunci când sunt solicitate anumite informații, vom verifica dacă sunt stocate, dacă da, le returnăm imediat, altfel o putem calcula și salva pentru o utilizare ulterioară. Această tehnică este extrem de utilă atunci când trebuie să folosim un algoritm complex pentru a primi un răspuns sau în cazul în care folosim o rețea lentă pentru a obține informații.
Deci, să ne uităm la cod pentru a ilustra această tehnică:
clasa Rocket getPath: -> @path? = @doMathComplexProcess ()Pentru a explica mai bine această porțiune de cod, o vom compila pentru a vedea cum CoffeeScript construiți JavaScript că tehnica noastră va trebui să ne salveze munca în dezvoltarea noastră, să vedem cum arată codul nostru:
MARI
Dar asta nu este tot ce putem face cu noua noastră tehnică CoffeeScript, putem chiar stoca mai multe valori folosind o structură de date, să vedem cum o putem face:
class SecurityGateway hasAccess: (guard) -> @access? = {} @access [guard.plate_number]? = verifyCredentials guard.plate_numberCeea ce face această porțiune de cod este că în obiectul nostru rezultatul este stocat pentru fiecare pază care a solicitat accesul, am avea nevoie doar de ceva unic pentru a le putea identifica în obiectul nostru, astfel încât să folosim numărul plăcii pentru această sarcină, să vedem cum este tradus codul nostru atunci când îl compilăm:
MARI
În cele din urmă vom vedea o modalitate de a transmite opțiuni unei funcții, aceasta nu este o funcționalitate specială a CoffeeScriptEste mai mult o convenție care folosește multe dintre caracteristicile limbii, folosindu-le într-un model ușor de înțeles și care este la fel de util în multe situații care pot apărea.
Cum functioneazã?Ideea din spatele acestui lucru este simplă, este să ai o funcție care acceptă acest lucru obiect opțiuni care poate conține chei asociative pentru argumentele funcției respective. Acest lucru face ca opțiunile să fie ușor de înțeles din codul în care sunt apelate, deoarece există acolade pentru a identifica ce face fiecare valoare. Acest lucru reduce, de asemenea, hassle de a urmări argumentele, precum și ordinea lor, deoarece cheile obiect nu sunt dependente de acest lucru și pot fi omise dacă nu sunt necesare.
Pentru a implementa obiecte opțiuni mai întâi vom folosi argumente opționale pentru a seta implicit un argument gol. În acest fel, atunci când efectuăm apelul, putem omite opțiunile în cazul în care valorile nu sunt necesare:
launchNave = (nume, opțiuni = {}) -> întoarcere dacă options.drift dry take off ()Acum vom folosi operatorul terțiar ?= pentru a completa valorile opțiunilor pe care dorim să le avem o valoare implicită specială:
launchNave = (nume, opțiuni = {}) -> options.count? = 10 console.log "# {i} …" pentru i în [options.count … 0] returnează dacă options.drift dry take off ()Definim o ultimă valoare și folosim operatorul ? în cazul în care este utilizat într-un singur loc:
launchSave = (name, options = {}) -> checkFuel (options.waitComb? 100) options.count? = 10 console.log "# {i} …" pentru i în [options.count … 0] returnează dacă opțiuni. uscat decola ()În cele din urmă, profităm de sintaxa permisivă a CoffeeScript pentru a trimite opțiunile la funcția noastră fără paranteze, oferindu-ne un apel destul de simplu și natural:
launchShip "Millennium Falcon", DryGear: adevărat, numărătoare inversă: 15Pentru a termina, vom compila fișierul nostru și vom vedea rezultatul codului nostru în JavaScript:
MARI