2. díl - Větvení a cykly v CoffeeScriptu

JavaScript CoffeeScript Větvení a cykly v CoffeeScriptu

Vítejte u druhého dílu o CoffeeScriptu. V minulém dílu jsme si udělali úvod do tohoto jazyka a zmínili základní syntaxi. Dnes si ukážeme větvení a cykly.

Větvení

Jak možná očekáváte, pro základní větvení použijeme tradiční slůvka if/else a jak jsme si již zvykli, vynecháme závorky:

x = 5

if x == 5
  alert 'ano'
else if x is 4 or x is 6
  alert 'těsně vedle'
else
  alert 'ne'

JavaScript:

var x;

x = 5;

if (x === 5) {
  alert('ano');
} else if (x === 4 || x === 6) {
  alert('těsně vedle');
} else {
  alert('ne');
}

Na kódu můžeme vypozorovat, že CoffeeScript převádí == na ===. Nutí vás tedy explicitně převádět hodnoty, jestliže např. chcete, aby se string '40' rovnal číslu 40. Také přidává aliasy různým operátorům (or je ||, is je === atd.), aby kód skutečně připomínal spíše jazyk nežli soubor matematických zápisů. Můžete však používat operátory jak je znáte z JS. Tabulku s různými operátory najdete na konci článku.

Z Ruby si CoffeeScript vypůjčil klíčové slovo unless, které je vlastně jen if not a můžeme použít i slovo then, aby se to hezky vešlo na jediný řádek:

unless false then console.log 2         # Vždy vypíše do konzole číslo 2.

Někdy můžete chtít vložit do proměnné hodnotu jen tehdy, když je splněna podmínka. K tomu můžete použít postfixový tvar:

kafe = 'Instant' if maloCasu

JavaScript:

var kafe;
if (maloCasu) {
  kafe = 'Instant';
}

Když přiřadíme větvení k proměnné, CoffeeScript jej převede na ternární operátor:

nalada = if den is 'vsedni' and not prazdniny then 'spatna' else 'dobra'

JavaScript:

var nalada;
nalada = den === 'vsedni' && !prazdniny ? 'spatna' : 'dobra';

Znalci Pythonu poznají zřetězené porovnávání proměnných, které CoffeeScript také podporuje:

if x > y < z >= a <= b is c isnt d
 console.log 'eh...ok...'

JavaScript:

if ((((((x > y && y < z) && z >= a) && a <= b) && b === c) && c !== d)) {
  console.log('eh...ok...');
}

Existenční operátor

Chceme-li zjistit, zda je proměnná/objekt definován(a) a není null, můžeme použít tzv. existenční operátor - ? (neplést s ternárním operátorem z jiných jazyků), který vrací true v případě, že proměnná není null nebo undefined.

alert 'To je katastrofa!' unless kavovar?

JavaScript:

if (typeof kavovar === "undefined" || kavovar === null) {
  alert('To je katastrofa!');
}

Lze použít i přiřazení hodnoty do proměnné v případě, že proměnná není null (musí být však deklarována):

x = undefined
x ?= 5

JavaScript:

var x;
x = void 0;
if (x == null) {
  x = 5;
}

Pozor! Na rozdíl od JS je v CoffeeScript slovo undefined klíčové, nemůžete mít tedy proměnnou s tímto jménem.

Existenční operátor jde použít samozřejmě i na objekty a funkce, takže lze tvořit klenoty jako:

objekt?.funkce? parametr if parametr?

JavaScript:

if (typeof parametr !== "undefined" && parametr !== null) {
  if (typeof objekt !== "undefined" && objekt !== null) {
    if (typeof objekt.funkce === "function") {
      objekt.funkce(parametr);
    }
  }
}

Zde už to začíná být opravdu nechutné a to jsme ani nenakousli OOP.

Switch

Dostali jsme se k poslední důležité části větvení a tou je samozřejmě switch. Jeho syntaxe v CoffeeScriptu je následující:

switch spanek
  when 'spatny' then mnozstviKofeinu = 'hodne'
  when 'prumerny' then mnozstviKofeinu = 'malo'
  when 'dobry' then do nepijKafe
  else alert '???'

JavaScript:

var mnozstviKofeinu;

switch (spanek) {
  case 'spatny':
    mnozstviKofeinu = 'hodne';
    break;
  case 'prumerny':
    mnozstviKofeinu = 'malo';
    break;
  case 'dobry':
    nepijKafe();
    break;
  default:
    alert('asi nespíš a jsi robot');
}

Pomocí switche lze také přiřazovat hodnoty místo několika if/else:

bodu = 83
znamka = switch
 when bodu < 60 then 5
 when bodu < 70 then 4
 when bodu < 80 then 3
 when bodu < 90 then 2
 else 1
# znamka === 2

JavaScript:

var bodu;
bodu = 83;

znamka = (function() {
  switch (false) {
    case !(bodu < 60):
      return 5;
    case !(bodu < 70):
      return 4;
    case !(bodu < 80):
      return 3;
    case !(bodu < 90):
      return 2;
    default:
      return 1;
  }
})();

Cykly

While

Základní while cyklus:

while podminka
 alert 'Cykluju...'                     # 'bezna' forma

alert 'Cykluju...' while podminka       # postfix forma

Oba kódy se zkompilují do:

while (podminka) {
  alert('Cykluju...');
}

Podobně jako unless je if not, until je while not:

alert 'Cykluju a podminka neni pravdiva...' until podminka

JavaScript:

while (!podminka) {
  alert('Cykluju a podminka neni pravdiva...');
}

Buďte s until i unless opatrní a nepřidávejte do podmínek negace, kód se bude špatně číst. Také by se s těmito slovy nemělo používat else.

Pomocí loop vytvoříme nekonečný cyklus:

loop
  alert 'Nekončíííím...'

JavaScript:

while (true) {
  alert('Nekončíííím...');
}

Když jsem v minulém díle psal, že „Co jde v JS, jde i v CoffeeScriptu“, nebyla to tak docela pravda, jak (nejen) nyní uvidíte. CoffeeScript nemá do-while cyklus, jelikož slovo do v CoffeeScriptu znamená 'volej funkci', jde jej však lehce nahradit následujícím zápisem:

loop
  ### tělo cyklu ###
  break unless podminka

JavaScript:

while (true) {
  /* tělo cyklu */
  if (!podminka) {
    break;
  }
}

Pomocí cyklu lze vytvářet pole:

cislo = 10
pole = while cislo--
  cislo

# pole = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

JavaScript:

var cislo, pole;
cislo = 10;

pole = (function() {
  var _results;
  _results = [];
  while (cislo--) {
    _results.push(cislo);
  }
  return _results;
})();

A když chceme, aby cyklus (ne)projížděl určitými hodnotami, použijeme slovo when. Toto se nám bude obzvlášť hodit později při for-in a for-of cyklech. Tento kód vám podobně jako v minulém příkladu vytvoří pole, ale bez sudých čísel:

cislo = 10
pole = while cislo-- when cislo % 2 isnt 0
  cislo
# pole = [9, 7, 5, 3, 1]

Část JS kódu po úpravě:

//...
  while (cislo--) {
    if (cislo % 2 !== 0) {
      _results.push(cislo);
    }
  }
//...

For

Pro základní for cyklus použijeme nám již známé n-tice:

for [1..10]             # dvě tečky <=
  console.log 'a'

for [1...10]            # tři tečky <
  console.log 'a'

JavaScript:

var _i, _j;

for (_i = 1; _i <= 10; _i++) {
  console.log('a');
}

for (_j = 1; _j < 10; _j++) {
  console.log(_j);
}

Kdybychom chtěli vypsat číslo, které je zrovna projížděno cyklem:

for i in [1..10]
  console.log i

V JS for cyklu bude následující:

for (i = _i = 1; _i <= 10; i = ++_i)

Není to zrovna nejelegantnější řešení, ale ta proměnná navíc snad nikoho nezabije. Mohli by jste samozřejmě proměnnou i nahradit _i, avšak pro každý další cyklus se tvoří nová proměnná (_j, _k atd...), a v .coffee souboru ji nevidíte, mohli byste s tímto způsobem narazit.

Nechceme vždy řídící proměnnou cyklu zvyšovat o 1, máme naštěstí k dispozici slovo by:

for i in [50..0] by -5

JavaScript:

for (i = _i = 50; _i >= 0; i = _i += -5)

Cyklus for-in v CoffeeScriptu používáme také na pole (Pozor! toto je velký rozdíl oproti JavaScriptu, kde je tento cyklus používán na objekty). Ukážeme si příklad na známém poli s kávami a nebudeme chtít rozpustnou:

kavy = ['Alžírská', 'Espresso', 'Cappuccino', 'Latte', 'Rozpustná', 'Vídeňská']

console.log kava for kava in kavy when kava isnt 'Rozpustná'

JavaScript:

var kava, kavy, _i, _len;
kavy = ['Alžírská', 'Espresso', 'Cappuccino', 'Latte', 'Rozpustná', 'Vídeňská'];

for (_i = 0, _len = kavy.length; _i < _len; _i++) {
  kava = kavy[_i];
  if (kava !== 'Rozpustná') {
    console.log(kava);
  }
}

Od ES6 existuje cyklus for-of pro pole, CoffeeScript však volí toto řešení kvůli kompatibilitě. Co je tedy ekvivalentem for-in v CoffeeScriptu? Ironicky je to for-of. Pro příklad si vypůjčíme kavárnu z prvního dílu:

kavarna =
 jmeno: "Kofeinová pumpa"
 rokZalozeni: 2001
 freeWifi: yes
 napojovyListek:
  kavy: [
   "Cappuccino"
   "Moccaccino"
   "Espresso"
  ]
  nealko: [
   "Sprite"
   "Pomerančový džus"
   "Voda z Marsu"
  ]

for nazev, hodnota of kavarna
 console.log "#{nazev} => #{hodnota}"

# jmeno => Kofeinová pumpa
# rokZalozeni => 2001
# freeWifi => true
# napojovyListek => [object Object]

Samotný cyklus v JS:

for (nazev in kavarna) {
  hodnota = kavarna[nazev];
  console.log("" + nazev + ": " + hodnota);
}

Co kdybychom chtěli vypsat prvních pět vlastností v objektu? Ani to není problém:

console.log (nazev for nazev of document)[0...5]
# vytvoří pole a vypíše: ["vlinkColor", "linkColor", "alinkColor", "fgColor", "bgColor"]

Nedávejte mezeru mezi pravou kulatou a levou hranatou závorku, program by pak dělal něco úplně jiného. Hlavně si zapamatuje - v JavaScriptu používáme of na pole, in na objekty, v CoffeeScriptu je to naopak.

Uf, tak jsme se dostali ke konci. Příště se podíváme na hlavní pilíř JavaScriptu - funkce. Na závěr zde máte tabulku s operátory, jak jsem slíbil:

is, == ===
isnt, != !==
not !
and &&
or ||
in není překládán (of)
of in
a // b Math.floor(a / b)
a %% b (a % b +b ) % b)

 

  Aktivity (1)

Článek pro vás napsal Yahkem
Avatar

Jak se ti líbí článek?
Celkem (5 hlasů) :
3.83.83.83.8 3.8


 


Miniatura
Předchozí článek
Úvod do CoffeeScriptu
Miniatura
Všechny články v sekci
CoffeeScript
Miniatura
Následující článek
Funkce a výjimky v CoffeeScript

 

 

Komentáře

Avatar
Michal Žůrek (misaz):

Docela mi tu začínají chybět příklady, kde se to používá v praxi. V prvním díle mi to až zas tak nevadilo, tu mi to začíná chybět.

Dále by mě zajimalo jak CoffeScript spolupracuje s JavaScriptem? zajímá mě co když chci v CoffeScriptu použít třeba existující knihovnu, která je napsaná v JavaScriptu.

Odpovědět 28.7.2014 19:47
Nesnáším {}, proto se jim vyhýbám.
Avatar
Yahkem
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
Yahkem:

Tutoriál je zaměřen převážně na syntaxi. V praxi se CoffeeScript používá např. s Node.js, podporuje jej také Ruby on Rails. Není žádný problém s používáním knihoven napsaných v JS (konec konců, CoffeeScript prakticky JE JS), třeba jQuery jde bez problémů. Pozor ale na překlepy - v .js knihovně máš funkci vykresliCaru(), v .coffee zavoláš vykreslicaru(), soubor se vesele zkompiluje a chybu zjistíš až za běhu.

 
Odpovědět 28.7.2014 22:05
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.