CoffeeScript – dlaczego wolę go od JavaScript
Wpis nie o Javie, ale nie samą javą programista żyje 🙂
Od JavaScript’u nie uciekniemy. Jeśli tylko robimy cokolwiek przy aplikacjach internetowych, to w mniejszym bądź większym stopniu dotkniemy JavaScript.
Osobiście nigdy nie lubiłem frontendu. Nie lubię JavaScripta. Jest mało czytelny, składniowe piekło, vary, średniki, i pisząc nieco bardziej skomplikowany kod po kilkunastu linijkach nie wiem o co chodzi. Ostatnio u mnie w firmie zaczęliśmy stosować CoffeeScript. I JavaScript stał się piękniejszy…
CoffeeScript
CoffeeScript to „mały język, który kompiluje się do javascripta”. Programiści, którzy dotknęli kiedyś Pythona szybko się odnajdą. Składniowo jest dość podobny.
Kilka elementów, w których się zakochałem to:
- brak średników
- brak klamer { i } zamiast nich, stosujemy wcięcia
- brak deklaracji zmiennych!! Każda zmienna jest z domysłu lokalna (var)
- mega intuicyjna składnia if
- funkcje jak lambdy
- domyślny return jako ostatnie polecenie (tutaj kilku osobom się to nie podoba, ja uważam to za fajny pomysł)
- w funkcjach nawiasy są opcjonalne, nie wymagane.
- klasy !! Koniec z prototypami i walką z językiem przy tworzeniu obiektów !!
Języka nauczyłem się w dwa wieczory czytając darmową książeczkę – Little Book Of CoffeeScript
CoffeeScript Instalacja
To co, napiszemy kilka linijek kodu? Zanim to zrobimy, musimy zainstalować kompilator Coffeescript.
Kompilator coffeescript wymaga nodejs, i zakładam, że jest już zainstalowany w systemie.
1 |
npm install coffee-script |
Gry node pobierze wszystkie zależności i zainstaluje coffee, możemy uruchomić go komendą coffee
Pełna lista parametrów uruchomieniowych kompilatora dostępna jest pod standardowym coffee –help
CoffeeScript Hello World
Jak zawsze trzeba zacząć od hello worlda 🙂
Będę pisał najpierw kod w Coffee, a poniżej pokazywać będę skompilowany kod do JavaScript.
1 |
console.log "Hello World!" |
1 2 3 4 |
(function() { console.log("Hello World!"); }).call(this); |
HA ! Ale cudo 🙂 Widać od razu bezpieczeństwo kodu, opakowanie go w funkcję.
Zróbmy coś bardziej zaawansowanego 😉
1 2 3 4 5 |
person = name: "Jan" lastName: "Kowalski" console.log person.name + " " + person.lastName |
1 2 3 4 5 6 7 8 9 10 11 |
(function() { var person; person = { name: "Jan", lastName: "Kowalski" }; console.log(person.name + " " + person.lastName); }).call(this); |
Już chyba widać różnicę?
To może napiszemy małą funkcję?
1 2 3 4 5 6 7 8 9 |
printPerson = (person) -> console.log person.name + " " + person.lastName person = name: "Jan" lastName: "Kowalski" printPerson(person) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
(function() { var person, printPerson; printPerson = function(person) { return console.log(person.name + " " + person.lastName); }; person = { name: "Jan", lastName: "Kowalski" }; printPerson(person); }).call(this); |
Żadnych dziwnych klamerek, żadnych średników, deklaracji zmiennych… czysto i schludnie !
A jakiegoś ifa może dodam ?
1 2 3 4 5 6 7 8 9 10 11 |
printPerson = (person) -> if person? and person.name? and person.lastName? console.log person.name + " " + person.lastName else console.log "osoby nie zdefiniowane" person = name: "Jan" lastName: "Kowalski" printPerson(person) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
(function() { var person, printPerson; printPerson = function(person) { if ((person != null) && (person.name != null) && (person.lastName != null)) { return console.log(person.name + " " + person.lastName); } else { return console.log("osoby nie zdefiniowane"); } }; person = { name: "Jan", lastName: "Kowalski" }; printPerson(person); }).call(this); |
Robi się coraz ciekawiej prawda? Jak widzicie w kodzie wynikowym pojawiły się same returny, jest to właśnie implicit return. Możemy nie chcieć, aby był return na console log…
1 2 3 4 5 6 7 8 9 10 11 |
printPerson = (person) -> if person? and person.name? and person.lastName? console.log person.name + " " + person.lastName else console.log "osoby nie zdefiniowane" return person = name: "Jan" lastName: "Kowalski" printPerson(person) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
(function() { var person, printPerson; printPerson = function(person) { if ((person != null) && (person.name != null) && (person.lastName != null)) { console.log(person.name + " " + person.lastName); } else { console.log("osoby nie zdefiniowane"); } }; person = { name: "Jan", lastName: "Kowalski" }; printPerson(person); }).call(this); |
Jak widać, jeśli podamy sam return bez parametru, to będzie oznaczało, że funkcja nic nie zwróci…
W wywołaniu printPerson specjalnie dodałem nawiasy, aby pokazać, że można je dodać i coffee sobie z nimi poradzi też 😉
A co z klasami ?
Utwórzmy jakąś 🙂
1 2 3 4 5 6 7 8 |
class Person constructor: (@name,@lastName) -> toString: -> @name + " " + @lastName person = new Person "Jan", "Kowalski" console.log person.toString() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(function() { var Person, person; Person = (function() { function Person(name, lastName) { this.name = name; this.lastName = lastName; } Person.prototype.toString = function() { return this.name + " " + this.lastName; }; return Person; })(); person = new Person("Jan", "Kowalski"); console.log(person.toString()); }).call(this); |
I pozamiatane 🙂
Zachęcam do pobawienia się coffee.. A jeśli do zabawy dołączymy jeszcze Angulara, to kod nagle się zrobi taki ładny i czytelny, że nawet taki zatwardziały anty-javascriptowiec jak ja się do niego przekona… 🙂