Bruker du CoffeeScript?

Det er ikke to måter: webutviklingsbransjen kan være utrolig vanskelig. Det er en som krever at vi kontinuerlig utdanner oss gjennom hele vår karriere. Ta noen år av, og plutselig finner du deg selv begravet av nye rammer, verktøy, beste praksis og preprosessorer. Det er riktig, kiddies, hvis du vil være en webutvikler, må du være ok med ideen om at skolingen din aldri vil ende (og du burde ikke ønske det).

CoffeeScript.org bør selvfølgelig være ditt første stopp når du lærer CoffeeScript. Dokumentasjonen er fantastisk.

Når vi anerkjenner at en viss prosentandel av hver uke skal brukes finjustere våre ferdigheter og lære nye ting, blir det utrolig viktig å bestemme hva som spesielt er å investere vår tid i. Tilsynelatende hver dag blir nye biblioteker eller verktøy utgitt for publikum. Men dette betyr ikke at vi skal kaste forsiktighet (og tid) til vinden og omfavne dem alle; ikke i det hele tatt. Vet sikkert et nysgjerrig sinn, men et sunt nivå av skepsis er avgjørende.

Uansett, visse verktøy hopper imidlertid raskt til toppen av den "nye og skinnende" -listen.

Dette er de typene som har potensial til å omdefinere hvordan vi bygger nettet. jQuery redefinerte måten vi spørre på og jobber med DOM. Backbone.js hjelper utviklere til å omforme spaghetti-koden til velstrukturerte og vedlikeholdbare moduler. Og bare kanskje, CoffeeScript vil gjenoppfinne måten vi fysisk skriver vårt JavaScript på.

Det er bare ett problem: CoffeeScript legger ikke til noe nytt på JavaScript-språket; Den tilbyr bare en forbedret syntaks (mange vil si drastisk forbedret), som i siste instans blir samlet inn i vanlig JavaScript. Så vårt dilemma er: I et miljø som allerede krever at vi lærer utallige språk, teknikker og mønstre, er det virkelig verdt tiden å investere for å lære enda en preprosessor? Vel, mens svaret på det spørsmålet sikkert kan diskuteres, i denne forfatterens mening, burde du absolutt grave inn!


Vent, hva er CoffeeScript igjen?

Det er mulig at dette er det første du har hørt om CoffeeScript. Hvis ikke, vær ikke redd det er bare akkurat nå begynt å virkelig plukke opp damp over utviklingssamfunnet.

I sin kjerne forvandler CoffeeScript, skapt av Jeremy Ashkenas, hva noen vil referere til som "stygge JavaScript" i ren og kortfattet kode. Det utvider ikke funksjonaliteten til JavaScript-språket; det lagrer bare en vakrere syntaks.

Den beste måten å demonstrere hva CoffeeScript tilbyr, er å ta en spasertur gjennom syntaksen.

Installasjon

"Try CoffeeScript" -fanen på CoffeeScript.org tilbyr sanntids kompilering; det er en utmerket måte å leke med syntaksen.)

Hvis du bare vil leke med syntaksen, kan du gå til CoffeeScript.org, og klikke på "Prøv CoffeeScript" -fanen. På den annen side, hvis du vil installere CoffeeScript lokalt, må du sørge for at du har oppdaterte kopier av både Node.js og npm (Node Package Manager) installert på systemet. Ikke bekymre deg; det er lett.

Deretter kan CoffeeScript installeres fra kommandolinjen:

npm installere -g kaffe-script

Det er det! Du er klar til å gå. Til se en fil, script.coffee, og kompilere det til script.js hver gang filen er lagret, innenfor kommandolinjen, bla til prosjektrotten din og skriv inn:

kaffe - klokke - kompilere script.coffee

I tillegg tilbyr mange redaktører, for eksempel TextMate og Sublime Text 2, bunter som gjør denne byggeprosessen til et enkelt tasteslag. Som et alternativ, se apper, som LiveReload og CodeKit, som håndterer "watch and compile" -oppgaven automatisk..

LiveReload automatiserer prosessen med å se og kompilere CoffeeScript-filer.)

variabler

Vurder følgende kodestykke:

var foo = 'bar'; var bar = 'baz';

I CoffeeScript, Var bør aldri brukes Faktisk vil motoren kaste en feil hvis du prøver å gjøre det. I stedet er alle variabler deklarert automatisk i det nåværende omfanget - noe som betyr at vi ikke lenger trenger å bekymre deg for å skape ubehagelige globale variabler.

Ovennevnte kode kan omskrives som:

foo = 'bar' bar = 'baz'

Når koden til slutt er kompilert til vanlig JavaScript, blir begge variabelnavnene deklarert øverst i funksjonsområdet, og deretter tildelt tilsvarende, slik som:

var bar, foo; foo = 'bar'; bar = 'baz';

semikolon

Mange JavaScript-utviklere hater det faktum at alle uttrykk skal ende med et semikolon.

var foo = 'bar';

Teknisk sett finner du at du ofte kan komme unna med å forlate semikolonene; men det er likevel gotchas involvert i denne tilnærmingen, og det er blitt ansett som en god praksis for alltid å inkludere dem for maksimal sikkerhet.

I CoffeeScript kan vi imidlertid vinkle farvel til dem for alltid. Som sådan kan den forrige kodebiten endres til:

foo = 'bar'

Parentes

Det kan ofte utelates ekstra signaler fra språk som Ruby, i CoffeeScript, parentes også. Dette forvandler tradisjonell JavaScript, for eksempel:

hvis (antar === 10) resultat = 'riktig'; 

inn i:

hvis gjetning == 10 resultat = 'riktig'

Enda bedre, vi kan være mer kortfattede ved å bruke en setningsmodifikator:

result = 'correct' hvis gjetning == 10

Mye renere og lesbar, va? "Sett resultat å "korrigere" hvis Gjett variabel er lik 10. "Utmerket!

Vær oppmerksom på at CoffeeScript kompilerer alt == inn i den strenge likestillingsversjonen, ===, som anbefalt av verktøy, som JS Lint.

aliaser

Du vil raskt finne ut at, i CoffeeScript, kan samme blokk kode omskrives på flere måter. Selv om du er fri til å ignorere dem, gir aliaser mulighet for mer menneskelige lesbare sammenligninger. Følgende grupperinger er identiske i både funksjonalitet og kompilering.

// likestilling lansering == 'go' lanseringen er 'go' // ulik lansering! = 'go' lansering er ikke 'go' // ikke returner falsk hvis! goForFlight returner falsk hvis ikke goForFlight returner falsk med mindre goForFlight // true return true retur på retur ja // falsk tilbakemelding falsk retur av retur Nei // og goForFlight && start () goForFlight og start () // eller goForFlight || forberede () goForFlight eller lagre ()

funksjoner

Funksjoner er et nøkkelområde der syntaksen er betydelig forskjellig fra JavaScript. En tradisjonell funksjon som bestemmer om det er betalingsdag - eller fredag ​​- kan se ut som:

var payDay = funksjon () returner ny dato (). getDay () === 5; // er det fredag ​​?? 

I et forsøk på å rydde opp roten, med CoffeeScript, kan denne funksjonen omskrives som:

payDay = -> ny dato (). getDay () == 5

Alternativt kan vi legge hele koden på en enkelt linje.

payDay = -> ny dato (). getDay () == 5

Det er to viktige ting verdt å merke seg her:

  1. funksjon() har blitt erstattet med ->.
  2. Den siste linjen av en funksjon vil alltid bli returnert. Som sådan, den komme tilbake Søkeordet kan bli fjernet i dette spesielle tilfellet.

Eventuelle relevante argumenter skal plasseres innenfor parentes, før ->. Kanskje betale dagen er på torsdag; I så fall kan funksjonen endres for å være mer fleksibel.

payDay = (dag) -> ny dato (). getDay () == dag

Men, hva hvis vi ønsker å tildele en standard lønnsdag fredag ​​(eller 5)? I vanlig JavaScript vil vi trolig gjøre det:

var payDay = funksjon (dag) dag || (dag = 5); returner ny dato (). getDay () === dag; 

Med CoffeeScript, derimot, kan vi forkorte dette sterkt.

payDay = (dag = 5) -> ny dato (). getDay () == dag

Kjekk!

objekter

Et typisk JavaScript-objekt kan rengjøres betydelig i CoffeeScript. Vurder følgende:

var person = ben: 2, hender: 2, fingre: 10

CoffeeScript lar oss fjerne Var søkeord, samt både de krøllete båndene og kommaene. På en enkelt linje er kommasene imidlertid fortsatt påkrevd.

person = ben: 2, hender: 2, fingre: 10

Men hvis vi plasserer hver eiendom på egen linje, kan de bli utelatt. Det samme gjelder for arrayer.

person = ben: 2 hender: 2 fingre: 10

Viktig: fordi CoffeeScript er avhengig av hvite rom, kan en enkelt feilkorrigert linje drastisk endre måten som koden er samlet på for JavaScript.

forståelse

Forståelse gjør det mulig for oss å enkelt omdanne ti kodelinjer til bare noen få. Det er egentlig en måte å skape uttrykk for å iterere over et gitt sett med elementer i en matrise eller et objekt.

For eksempel, i stedet for å bruke den typiske til uttalelse - og "caching" som følger med iterating over en matrise - vi kan i stedet bruke for i.

La oss forestille oss at vi trenger å iterere over en rekke tegn. Med tradisjonell JavaScript kan vi gjøre det:

var tegn = ['Marty', 'Doc', 'Biff']; for (var i = 0, len = characters.length; i < len; i++ )  console.log("Get %s to the time machine", characters[i]); 

Det er absolutt ikke pen; men hvis vi i stedet bruker CoffeeScript, kan det være vakkert.

tegn = ['Marty', 'Doc', 'Biff'] for person i tegn console.log "Få% s til tidsmaskinen", person

Gjør det ikke så bra å skrive? Sikkert, jeg kan ikke være den eneste!

Som du finner snart, kan vi til og med bruke strenginterpolering for å forbedre koden ytterligere - men jeg kommer foran meg selv.

Det er et problem, skjønt: Vi har utilsiktet rettet Biff til tidsmaskinen, noe som ikke er en god ide. La oss endre koden for å angi at den bare skal logge strengen til konsollen på betingelse av at den nåværende personen i arrayet ikke er Biff. I CoffeeScript, hvis vi utnytter filtre, er det en cinch.

tegn = ['Marty', 'Doc', 'Biff'] for person i tegn når personen ikke er 'Biff' console.log "Få% s til tidsmaskinen", person

Jepp; Behandlingen krevde totalt fire menneskelige lesbare ord.

Nå, hvis vi ønsker det, kan vi gjøre disse løkkene mer lesbare ved å bruke listeforståelse. Å sløyfe gjennom tegn array, og logg hver persons navn til konsollen:

console.log person for person i tegn

Eller, som et annet eksempel, for å hente alle ankerkoder fra siden (ved hjelp av jQuery's kart metode), lagre hvert anker er href verdien i en matrise, og til slutt sløyfe gjennom denne matrisen, og logg verdiene til konsollen, med vanlig JavaScript, ville vi gjøre:

var linker = $ ('a'). kart (funksjon () return this.href;); console.log (links.join (','));

Med CoffeeScript har vi imidlertid bedre valg:

console.log (lenke for lenke i $ ('a'). kart -> @href) .join ','

Som et siste eksempel, hva om vi hadde en rekke personobjekter:

folk = [navn: 'Jeffrey' alder: 27, navn: 'John' alder: 13, navn: 'Jan' alder: 42]

Vår jobb er å skape et nytt utvalg, kalt av alder, og gjør det til en liste over bare gjenstandene hvor personen er 21 år eller eldre. Igjen, med vanlig vanilje JavaScript, kan vi gjøre:

var ofAge = []; for (var i = 0, len = people.length; i < len; i++ )  if ( people[i].age >= 21) ofAge.push (folk [i]); 

Ja, det er ganske ordentlig for en så enkel oppgave. Med CoffeeScript, la oss redusere dette til en enkelt linje, ved hjelp av forståelse.

ofAge = (p for p i folk når p.age> = 21)

Bam! Ved å pakke inn alt som skjer etter likestilt innenfor parentes, spesifiserer vi at av alder variabel skal være lik resultatene av den operasjonen, som vil være en matrise. Så arrayet vil bli bygget, og deretter tildelt til av alder. Når du er forvirret, les bare uttrykket fra venstre til høyre. "Skyv personobjektet til resultater array, for hver person i mennesker array ... like lenge som personen er alder Eiendommen er større enn eller lik 21. " når Søkeord kalles et filter, og kan være utrolig kraftig. Innrøm det: du begynner å salivere.

Stringinterpolering

I den forrige delen brukte vi en ganske typisk metode for å binde en variabel til en streng.

console.log "Få% person til tidsmaskinen", person

På samme måte som språk, som Ruby, tilbyr CoffeeScript strenginterpolering via # syntaks. Denne koden kan omskrives, slik som:

console.log "Få # person til tidsmaskinen"

Vær oppmerksom på at, som de fleste språk, for å dra nytte av strenginterpolering, må du bruke dobbelt anførselstegn, i stedet for enkelt.

Funksjon Binding

Tenk på den ganske vanlige oppgaven med å cache en referanse til dette, slik at når konteksten endres - som for eksempel i tilbakekallingen av en jQuery-hendelse-binding - kan vi fortsatt få tilgang til den cachede plasseringen. Her er et eksempel:

var selv = dette; $ ('h1'). på ('klikk', funksjon () // 'dette' refererer nå til ankeret som ble klikket // bruk selv i stedet self.someMethod (););

CoffeeScript gir den "fete pilen", eller =>, som kan være av stor hjelp. Hvis vi endrer -> til =>, Bak kulissene vil CoffeeScript cache en referanse til dette. Deretter, innenfor funksjonen, alle referanser til dette vil bli dynamisk erstattet med den bufret versjonen.

For å illustrere denne ideen, følger følgende kode:

$ ('h1'). på 'klikk', => this.someMethod ()

... vil kompilere til:

var _this = dette; $ ('h1'). på ('klikk', funksjon () return _this.someMethod (););

klasser

CoffeeScript gir en nyttig klasse syntaks, for de som foretrekker en mer klassisk tilnærming til å strukturere sin kode. For eksempel ved å bare skrive klasse person, CoffeeScript vil kompilere denne koden til:

var Person; Person = (funksjon () funksjon Person ()  returperson;) ();

Legg merke til hvordan Person variabel er lik et uttrykk for selvpåkallingsfunksjon som returnerer det indre Person funksjon. Bør vi trenge å utføre litt kode umiddelbart etter instansiering, som ligner på PHP __construct metode, vi kan plassere vår i det kode i konstruktør metode av klasse, som så:

klasse Personkonstruktør: (navn, alder) -> this.name = navn this.age = alder

De konstruktør Metoden kan ikke kalles eksplisitt; I stedet utløses det dynamisk når du snakker om klassen. Denne koden kan imidlertid forbedres; CoffeeScript gir litt ekstra sukker som kan forkorte det. I CoffeeScript, the @ symbolet vil alltid referere til dette, eller forekomsten av Person. Som sådan, heller enn this.age, vi kan i stedet bruke @alder, hvilke Ruby-utviklere vil bli kjent med. Koden ovenfor kan omskrives som:

klasse Personkonstruktør: (navn, alder) -> @name = navn @age = alder

Enda bedre, men vi kan ta ting et skritt videre. Disse instansvariablene kan settes på en annen måte:

klasse Personkonstruktør: (@name, @age) ->

Ikke dårlig, va? På dette tidspunktet, forlenge Personprototype med flere metoder, oppretter vi bare nye metoder, på samme måte som vi vil legge til metoder til et objekt. Bak kulissene vil CoffeeScript feste metoden til prototypen. La oss legge til en metode som bestemmer personens fødselsår.

klasse Personkonstruktør: (@name, @age) -> getBirthYear: -> new Date (). getFullYear () - @age

Denne vakre, rene koden, en gang kompilert til JavaScript, vil være:

var Person; Person = (funksjon () funksjon Person (navn, alder) this.name = name; this.age = alder; Person.prototype.getBirthYear = function () return new Date (). GetFullYear () - dette. alder;; return Person;) ();

Så, vi har effektivt kuttet antall linjer fra seksten ned til fire. For å instantiere denne nye klassen kan vi skrive:

mann = ny person ('Jeffrey', 27) man.getBirthYear () # 1985

Enda bedre, for å lage barnklasser, som strekker seg Person, vi trenger bare å bruke forlenge søkeord:

klasse barn utvider person

På dette punktet, Barn Nå har du tilgang til alle egenskapene og metodene fra Person klasse, og kan referere eller overskrive dem etter vilje.


Skal du bruke CoffeeScript?

Til tross for alt dette strålende sukker, står vi fortsatt med spørsmålet: bør vi bruke CoffeeScript i produksjon? Vel, John Q. Reader, det er stort sett opp til deg. Det er gyldige argumenter for og imot det. Nay-Sayers vil peke på det faktum at debugging potensielt kan bli en vanskeligere oppgave fordi du ikke jobber spesielt med det samleobjektet JavaScript. Du er feilsøkingskode du ikke skrev. Det kan være en kamp.

"Jeg tror CoffeeScript er et strålende eksperiment. CoffeeScript tar de gode delene, og legger en minimal syntaks på toppen av det, som er nydelig. Jeg anbefaler ikke å bruke den i produksjon, fordi den kommer med sin egen verden av problemer. - Douglas Crockford "

Man kan også argumentere for at for mye avhengighet av abstraksjoner som dette kan føre til at utvikleren har en mindre forståelse av JavaScript som helhet. Fordi så mange gode fremgangsmåter blir bakt inn i kompilatoren, forenkler det byrden på utvikleren for å huske disse beste praksisene, for eksempel å unngå globals og heise variabler. Hvorvidt denne typen automatisering er en god ting, er opp til debatt.

"En best praksis som kan håndheves og genereres av en kompilator, er bedre enn en best practice som må huskes og manuelt skrives ut hver gang." - Jeremy Ashkenas

Å spille djevelens talsmann, det samme kunne ha blitt sagt for jQuery. Oppfordrer jQuery til en ny ras av utvikler som aldri virkelig lærer vanilje JavaScript? Absolutt ikke; Om noe, har det bidratt sterkt til gjenoppblussen av JavaScript-språket.

Mens CoffeeScript-syntaksen i utgangspunktet kan bli mer kjent og innbydende til Ruby og Python-utviklere som er redd for JavaScript, vil det forhåpentligvis oppmuntre dem til å grave dypere inn i det underliggende språket.


Sammendrag

For å samle flere CoffeeScript-meninger fra JavaScript-mestere - på begge sider av gjerdet - se "Skal du lære CoffeeScript" fra Nettuts +. )

Endelig er CoffeeScript bare JavaScript. Den gir en vakker syntaks som sitter på toppen av språket. Fordelene er åpenbare: Koden følger automatisk god praksis, og blir kortere, mindre feilgjennomgang og betydelig mer lesbar. Men igjen, feilsøking, som kan ta opp betydelig tid i en utviklers arbeidsflyt, er en bekymring.

Valget er opp til deg! Som for din, vel, jeg kan ikke forestille meg å gå tilbake. Jeg har alt med CoffeeScript.

Videreutdanning

  • Cleaner Code With CoffeeScript (Kommer snart til Tuts + Premium!)
  • Nettuts +: Skal du lære CoffeeScript?
  • CodeSchool: En Sip of CoffeeScript
  • Pragmatisk bokhylle: CoffeeScript - Fremskyndet JavaScript-utvikling