IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 2 - Větvení a cykly v CoffeeScriptu

V minulém dílu, Úvod do CoffeeScriptu, 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. 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)

Příště, v lekci Funkce a výjimky v CoffeeScript, se podíváme na hlavní pilíř JavaScriptu - funkce.


 

Předchozí článek
Úvod do CoffeeScriptu
Všechny články v sekci
CoffeeScript
Přeskočit článek
(nedoporučujeme)
Funkce a výjimky v CoffeeScript
Článek pro vás napsal Yahkem
Avatar
Uživatelské hodnocení:
6 hlasů
...
Aktivity