/* Datové typy */
/** Primitiva **/
12345                      // Číslo (v desítkové soustavě,
0x3039                     ///       v šestnáctkové soustavě,
0o30071                    ///       v oktalové soustavě, -- Novinka ECMAScriptu 6
0b11000000111001           ///       v binární soustavě)  -- Novinka ECMAScriptu 6
NaN                        //// Hodnota Not a Number (navrácena např. při dělení nulou)
Infinity                   //// Pozitivní nekonečno
-Infinity                  //// Negativní nekonečno

"ahoj 'světe'"             // Textový řetězec
'ahoj "světe"'
"1, 2, 3, " + 4 + ', ' + (2 + 3)
`1, 2, 3, ${4}, ${2 + 3}`  //// Interpolovaný řetězec -- Novinka ECMAScriptu 6

true                       // Pravdivostní (boolean) hodnota
false

undefined                  // Nedefinovaná, prázdná hodnota
Symbol()                   // Symbol -- Novinka ECMAScriptu 6

/** Referenční typy **/
[ 1, 2, 3, [4, 5] ]        // Pole             (objekt `Array`)
new Array(1, 2, 3, new Array(4, 5))

function a(b) { return b } // Funkce           (objekt `Function`)
var a = function(b) { return b }
var a = (b) => b           //// Lambda syntax -- Novinka ECMAScriptu 6
var a = new Function("return arguments[0];")

/ahoj\s*světe/ig           // Regulární výraz  (objekt `RegExp`)
new RegExp("ahoj\\s*světe", "ig")

new Date                   // Datum            (objekt `Date`)
new Error                  // Výjimka          (objekt `Error`)
new Number(12345)          // Zabalené číslo   (objekt `Number`)
new String("foo bar")      // Zabalený řetězec (objekt `String`)
new Boolean(true)          // Zabalený boolean (objekt `Boolean`)
new Set([1, 2, 3, 1, 2])   // Množina          (objekt `Set`) -- Novinka ECMAScriptu 6

({ ahoj: "světe" })        // Obecný objekt   (objekt `Object`)
null                       //// Nedefinovaný objekt

/* Základní aritmetika */
1 + (2 * 3) - 4 / 5        // Aritmetické operátory
6 % 7                      //// Zbytek po celočíselném dělení
Math.abs(-47.125)          // Absolutní hodnota argumentu
Math.cos(0)                // Kosinus
Math.acos(1)               // Arkus kosinus
Math.sin(Math.PI / 2)      // Sinus
Math.asin(1)               // Arkus sinus
Math.tan(Math.PI / 4)      // Tangens
Math.atan(1)               // Arkus tangens
Math.atan2(1, 1)           // Úhel mezi osou x a daným bodem
Math.ceil(1.05)            // Zaokrouhlování směrem nahoru
Math.ceil(1.8) 
Math.round(1.05)           // Aritmetické zaokrouhlování
Math.round(1.8) 
Math.floor(1.05)           // Zaokrouhlování směrem dolů
Math.floor(1.8) 
Math.pow(2, 8)             // Výpočet osmé mocniny dvou
Math.pow(Math.E, 8)        // Výpočet osmé mocniny Eulerova čísla
Math.exp(8) 
Math.pow(2, 1/2)           // Výpočet druhé odmocniny dvou
Math.sqrt(2) 
Math.log(2)                // Přirozený logaritmus
Math.min(1, 2, 3, 4, 5)    // Nalezení nejmenšího argumentu
Math.max(1, 2, 3, 4, 5)    // Nalezení největšího argumentu

/* Operátory */
/** Relační operátory **/
1 < 2                      // Je menší než
3 > 2                      // Je větší než
3 >= 3                     // Je větší nebo rovno než
3 <= 3                     // Je menší nebo rovno než
3 == 3                     // Je rovno
"3" == 3                   //// Operátor rovnosti provádí konverze primitiv.
"3" != 3                   // Není rovno
3 === 3                    // Je identické
"3" === 3                  //// Operátor identity konverze primitiv neprovádí.
"3" !== 3                  // Není identické
"foo" === "foo"            //// Primitiva jsou identická, pokud si odpovídají hodnotou.
[1, 2] === [1, 2]          //// Referenční typy jsou identické, pokud jde o totožný objekt.

/** Logické operátory **/
true  && true              // Logické AND
true  && false
false && true
true  || true              // Logické OR
true  || false
false || true
!true                      // Logické NOT
!false

/** Bitové operátory **/
0b0011 & 0b1100                      // Bitové AND
0b0011 & 0b0011
0b0011 | 0b1100                      // Bitové OR
0b0011 | 0b0011
0b0011 ^ 0b1100                      // Bitové XOR
0b0011 ^ 0b0011
~0b11111111111111111111111111111111  // Bitová inverze
~0b00000000000000000000000000000000
0b0001 << 3                          // Bitový posun doleva
0b1000 >> 3                          // Bitový posun doprava
-0b1000 >>> 3                        // Bitový posun doprava s doplňováním nul
-0b1000 >>  3

/** Proměnné a přiřazovací operátory **/
var a                      // Deklarace proměnné
var a = 1                  // Deklarace a přiřazení hodnoty proměnné
var a; a = 1

a += 1                     // Inkrementace
a = a + 1
a++                        //// Tento operátor navrátí hodnotu proměnné před inkrementací
++a                        //// Tento operátor navrátí hodnotu proměnné po inkrementaci

a -= 1                     // Dekrementace
a = a - 1
a--                        //// Tento operátor navrátí hodnotu proměnné před dekrementací
--a                        //// Tento operátor navrátí hodnotu proměnné po dekrementaci

a *= 2                     // Násobení
a /= 2                     // Dělení
a %= 2                     // Zbytek po celočíselném dělení


/** Další operátory **/
true  ? 1 : "foo"                            // Ternární operátor
false ? 1 : "foo"
typeof 12345                                 // Detekce primitivního datového typu
typeof "foo bar"
typeof true
typeof undefined
typeof Symbol()
[ 1, 2, 3, [4, 5] ]        instanceof Array  // Detekce referenčního datového typu
function a(b) { return b } instanceof Function
/ahoj\s*světe/ig           instanceof RegExp
new Date                   instanceof Date
new Error                  instanceof Error
new Number(12345)          instanceof Number
new String("foo bar")      instanceof String
new Boolean(true)          instanceof Boolean
new Set([1, 2, 3, 1, 2])   instanceof Set
({ ahoj: "světe" })        instanceof Object
"ahoj" in { ahoj: "světe" }                  // Kontrola existence klíče v objektu
"foo"  in { ahoj: "světe" }

/* Řídicí struktury */
if (a === 1)               // Řídicí struktura `if` - `else` provede kód mezi
  "a se rovná 1"           /// `if` a `else`, pokud je splněna podmínka v záhlaví.
else {                     /// V opačném případě se provede kód za nepovinným
  "už tu máme dva výrazy"  /// `else`. Pokud kód obsahuje více než jeden výraz,
  "a se nerovná 1"         /// je nutné jej obalit do složených závorek.
}

var str = "Počítáme: " + a /// Cyklus `while` provádí následující kód, dokud podmínka
while (a < 10) {           /// v záhlaví cyklu zůstává platná.
  a += 1
  str += ", " + a
}
str

var str = "Počítáme: " + a /// Cyklus `do` - `while` provádí následující kód, dokud
do {                       /// podmínka v záhlaví cyklu zůstává platná. Na rozdíl
  a += 1                   /// od cyklu `while` k prvnímu průchodu cyklem dojde vždy
  str += ", " + a          /// a podmínka se kontroluje až při následujících průchodech.
} while(a === "nesmysl")
str

var str = "Počítáme: 1"      // Cyklus `for` nejprve provede první příkaz záhlaví a
for (var a = 2; a < 10; a++) /// zadeklaruje uvedené proměnné. Následně provádí následující
  str += ", " + a            /// kód, dokud druhý výraz v záhlaví zůstává platný. Po každé
str                          /// iteraci se vykoná třetí výraz v záhlaví.

var produkty = {           // Cyklus `for` - `in` provádí následující kód pro veškeré
  jablek:  "mošt",         /// klíče, které se nachází v příslušném objektu.
  jahod:   "marmeláda",
  rozinek: "zavařenina" };
var str = "";
for (var klíč in produkty)
  str += `Z ${klíč} se připravuje ${produkty[klíč]}. `
str

var produkty = new Set([      // Cyklus `for` - `of` provádí následující kód pro veškeré
  "mošt", "marmeládu", "zavařeninu" ]); /// hodnoty iterovatelného objektu. Jedná se
var str = "Můžeme vyprodukovat:"; /// o novinku ECMAScriptu 6.
for (var produkt of produkty)
  str += `\n * ${produkt}`
str

/* Výjimky */
try {
  throw new Error("Neočekávaná výjimka")
} catch (e) {
  "Došlo k následující chybě: " + e.message
} finally {
  // Tento kód se provede vždy.
}
