rozdzia: Dziedziczenie
==================
this.prototype = {constructor: this};
    
    
====================================
Function.method('new', function () {

   // Tworzymy nowy obiekt dziedziczcy z prototypu konstruktora.

   var that = Object.beget(this.prototype);

   // Wywoujemy konstruktor, wic this do nowego obiektu.

   var other = this.apply(that, arguments);

   // Jeli zwracana warto nie jest obiektem, 
   // podmie j na nowo utworzony obiekt.

   return (typeof other === 'object' && other) || that;
});
    
    
====================================
var Mammal = function (name) {
    this.name = name;
};

Mammal.prototype.get_name = function (  ) {
    return this.name;
};

Mammal.prototype.says = function (  ) {
    return this.saying || '';
};
    
    
====================================
var myMammal = new Mammal('Mj ssak');
var name = myMammal.get_name(  ); // 'Mj ssak'
    
    
====================================
var Cat = function (name) {
   this.name = name;
   this.saying = 'miau';
};

// Zastpujemy Cat.prototype instancj Mammal

Cat.prototype = new Mammal();

// Rozszerzamy nowy prototyp metodami purr i get_name

Cat.prototype.purr = function (n) {
   var i, s = '';
   for (i = 0; i < n; i += 1) {
      if (s) {
         s += '-';
      }
      s += 'r';
   }
   return s;
};
Cat.prototype.get_name = function () {
      return this.says() + ' ' + this.name + ' ' + this.says();
};

var myCat = new Cat('Kicia');
var says = myCat.says();  // 'miau'
var purr = myCat.purr(5);  // 'r-r-r-r-r'
var name = myCat.get_name();  // 'miau Kicia miau'

    
====================================
Function.method('inherits', function (Parent) {
    this.prototype = new Parent(  );
    return this;
});
    
    
====================================
var Cat = function (name) {
    this.name = name;
    this.saying = 'meow';
}.
    inherits(Mammal).
    method('purr', function (n) {
        var i, s = '';
        for (i = 0; i < n; i += 1) {
            if (s) {
                s += '-';
            }
            s += 'r';
        }
        return s;
    }).
    method('get_name', function (  ) {
        return this.says(  ) + ' ' + this.name +
                ' ' + this.says(  );
    });
    
    
====================================
var myObject = maker(f, l, m, c, s);
    
    
====================================
var myObject = maker({
    first: f,
    last: l,
    state: s,
    city: c
});
    
    
====================================
var myMammal = {
    name : 'Mj ssak',
    get_name : function (  ) {
        return this.name;
    },
    says : function (  ) {
        return this.saying || '';
    }
};
    
    
====================================
var myCat = Object.beget(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function (n) {
    var i, s = '';
    for (i = 0; i < n; i += 1) {
        if (s) {
            s += '-';
        }
        s += 'r';
    }
    return s;
};
myCat.get_name = function (  ) {
    return this.says + ' ' + this.name + ' ' + this.says;
};
    
    
====================================
var block = function () {

   // Zapamitujemy dotychczasowy zasig. Tworzymy nowy zasig,
   // ktry bdzie zawiera wszystko to, co dotychczasowy.

   var oldScope = scope;
   scope = Object.beget(scope);

   // Przechodzc nad lewym nawiasem klamrowym wchodzimy do nowego zasigu.

   advance('{');

   // Analizujemy tekst uywajc nowego zasigu.

   parse(scope);

   // Przechodzc nad prawym nawiasem klamrowym wychodzimy z zasigu
   // i przywracamy stary zasig.
   
   advance('}');
   scope = oldScope;
};

    
====================================
var constructor = function (spec, my) {
   vat that, inne prywatne zmienne instancyjne;
   my = my || {};

   // tu dodajemy do obiektu my zmienne i funkcje wspdzielnone 

   that = nowy obiekt;

   // tu dodajemy do obiektu that metody uprzywilejowane

   return that;
}
    
    
====================================
my.member = value;
    
    
====================================
var methodical = function (  ) {
    ...
};
that.methodical = methodical;
    
    
====================================
var mammal = function (spec) {
   var that = {};

   that.get_name = function () {
      return spec.name;
   };

   that.says = function () {
      return spec.saying || '';
   };

   return that;
};

var myMammal = mammal({name: 'Mj ssak'});
   
    
====================================
var cat = function (spec) {
    spec.saying = spec.saying || 'meow';
    var that = mammal(spec);
    that.purr = function (n) {
        var i, s = '';
        for (i = 0; i < n; i += 1) {
            if (s) {
                s += '-';
            }
            s += 'r';
        }
        return s;
    };
    that.get_name = function (  ) {
        return that.says(  ) + ' ' + spec.name +
                ' ' + that.says(  );
    return that;
};

var myCat = cat({name: 'Kicia'});
    
    
====================================
Object.method('superior', function (name) {
    var that = this,
        method = that[name];
    return function (  ) {
        return method.apply(that, arguments);
    };
});
    
    
====================================
var coolcat = function (spec) {
   var that = cat(spec), 
       super_get_name = that.superior('get_name');
   that.get_name = function (n) {
      return 'Teraz ' + super_get_name() + ' w nowej, lepszej wersji';
   };
   return that;
};

var myCoolCat = coolcat({name: 'Kocur'});
var name = myCoolCat.get_name();  // 'Teraz miau Kocur miau w nowej, lepszej wersji'
   
    
====================================
var eventuality = function (that) {
   var registry = {};
   
   that.fire = function (event) {
   
      // Wywoujemy zdarzenie na obiekcie. Zdarzenie moe by albo 
      // acuchem zawierajcym nazw zdarzenia, lub obiektem zawierajcym
      // waciwo type, ktra przechowuje nazw zdarzenia. Procedury obsugi
      // zdarze zarejestrowane przez metod on, ktrych nazwa pokrywa si 
      // z nazw zdarzenia, zostan wywoane.

      var array,
          func, 
          handler,
          i, 
          type = typeof event === 'string' ? event : event.type;
      
      // Jeli tablica procedur istnieje dla tego zdarzenia, wwczas
      // wywoujemy kolejno kad procedur z tablicy.
      
      if (registry.hasOwnProperty(type)) {
         array = registry[type];
         for (i = 0; i < array.length; i += 1) {
            handler = array[i];
            
            // Obiekt handler zawiera waciwo method i opcjonaln list parametrw. 
            // Jeli method jest nazw, wyszukujemy odpowiedni funkcj.

            func = handler.method;
            if (typeof func === 'string') {
               func = this[func];
            }

            // Wywoujemy procedur. Jeli byy podane parametry, przekazujemy je.
            // Jeli nie, przekazujemy obiekt zdarzenia.

            func.apply(this, handler.parameters || [event]);
         }
      }
      return this;
   };

   that.on = function (type, method, parameters) {

      // Rejestrujemy zdarzenie. Tworzymy rekord z procedur obsugi zdarzenia.
      // Dodajemy go do listy procedur obsugi, tworzc now, jeli jeszcze 
      // nie istnieje dla tego typu. 

      var handler = {
         method: method,
         parameters: parameters
      };
      if (registry.hasOwnProperty(type)) {
         registry[type].push(handler);
      } else {
         registry[type] = [handler];
      }
      return this;
   };
   return that;
};
    
    
====================================
eventuality(that);
    
    
==================