JavaScriptové perličky V.

Jednou ze zajímavostí JavaScriptu je, že každý objekt má vlastnost prototype. Tato vlastnost je objekt, s prazvláštním chováním – jakoukoliv jeho vlastnost budou mít všechny instance třídy jeho vlastníka. Zmatené? Třeba pomůže příklad:

objekt1 = new Trida();

objekt1.prototype.vlastnost = 377;
// nebo: Trida.prototype.vlastnost = 377;

objekt2 = new Trida();

document.write(objekt2.vlastnost); // 377
document.write(objekt1.vlastnost); // 377

Jak je vidět, vlastnosti z prototypu se do instancí objektů doplňují i zpětně.

Prototypování se dá hezky využít ve spojitosti s objektovými literály při definici nové třídy:

function Trida() {}; // konstruktor;

Trida.prototype = {
  vlastnost1: null,
  vlastnost2: null,
  ...
  vlastnostN: null,
}

Samozřejmě, vlastnosti objektů jde takto nastavovat v konstruktoru (this.vlastnost1 = null) a je to i výhodnější, protože některé vlastnosti se typicky inicializují na základě parametrů, které konstruktoru předáváme, a jejich hodnoty tedy nejsou při tvorbě prototypu známy. Z hlediska čistoty kódu je lepší mít nastavování všech vlastností (i těch inicializovaných staticky) na jednom místě a konstruktor je na to nejvhodnější.

Na co se tedy nastavování vlastností v prototypu naopak hodí? Na definici metod objektů. Ty se určitě nijak nemění a dají se v prototypu nastvit pomocí lambda funkcí:

Trida.prototype = {
  secti: function (a, b) {
    return a + b;
  },
  odecti: function (a, b) {
    return a - b;
  }
}

To už skoro vypadá jako deklarace třídy v nějakém klasickém objektovém jazyce, a opravdu to funguje úplně stejně. Pomocí prototypů se dá také v JavaScriptu definovat dědičnost, ale o tom až někdy příště. I když bystřejší čtenáři by si to možná už po dnešním dílu uměli dát dohromady...