Skip to content

Instantly share code, notes, and snippets.

@MatteoOreficeIT
Last active March 21, 2019 13:54
Show Gist options
  • Save MatteoOreficeIT/e40491b13888c69802c684a20df894ff to your computer and use it in GitHub Desktop.
Save MatteoOreficeIT/e40491b13888c69802c684a20df894ff to your computer and use it in GitHub Desktop.
kendo.Class.extend OO inheritance facility explained
// var ClasseFiglia = Class.extend(...);
// oppure
// var ClasseFiglia = ClassePadre.extend(...);
// crea una funzione costruttore ClasseFiglia ( detta classe in OOP )
// che si comporta secondo i meccanismi dell ereditarieta'
// Object Oriented, tale costruttore/funzione si puo usare come :
// var instance = new ClasseFiglia({...})
// e generare istanze di quella classe
// Si puo legare su proto.init un costruttore oltre
// alla dichiarazione di proprieta ( condivise ) e metodi che appunto finiranno sul prototype
// della nuova funzione costruttore ( ClasseFiglia )
// nul-op function
function Class() {}
Class.extend = function (proto) {
// base e' un costruttore utilizzato per allocare quello che sara'
// il prototype della nuova classe ClasseFiglia, un oggetto dove e' possibile
// installare metodi e proprieta' comuni a tutti gli oggetti stampati con new ClasseFiglia()
// NOTA BENE: comuni solo alle istanze stampate/create con ClasseFiglia
var base = function () {
},
member,
// e' l oggetto funzione costruttore da estendere
// nel caso base that === Class, ovvero quando var ClasseFiglia = Class.extend({...})
that = this, // ClassePadre
// subclass diventa == a init, ovvero un costruttore utente oppure e' una funzione che ....
subclass = proto && proto.init ? proto.init : function () {
// ....chiama la funzione costruttore da estendere ovvero ClassePadre e gli passa l'oggetto
// this che e' stato allocato via new, questo e' equivalente a chiamare il costruttore padre in OOP.
// -------------------------------------------------------------------------------------------------
// In un diretto discendente di Class esegue function Class() { } ovvero non fa nulla
// Nel metodo init si puo usare ClassePadre.fn.init.call(that, element, options) per chiamare
// il costruttore della classe ClassePadre
that.apply(this, arguments);
},
fn;
// Faccio puntare base.prototype a quello della funzione da estendere
// appunto allo scopo di creare una catena di prototipi.
// Tutte le istanze di subclass/ClasseFiglia avranno nella propria catena prototipale
// that.prototype, poiche' indirettamente :
// >>> ClasseFiglia.prototype.__proto__ == base.prototype , poiche' creato con new base()
// ma base.prototype == ClassePadre.prototype
// (new ClasseFiglia)[[__PROTO__]] -> new base()
// (new ClasseFiglia)[[__PROTO__]][[__PROTO__]] -> ClassePadre.prototype
// this/that ricordiamo e' una funzione costruttore che per noi rappresenta
// la Classe esistente da estendere ovvero ClassePadre.
base.prototype = that.prototype;
// nota che qui si perde il prototype originale di subclass
// e subclass.prototype.constructor non puntera piu a subclass
// ma a base ...
fn = subclass.fn = subclass.prototype = new base();
// Per ogni membro di proto:
// 1. se member è un object e pure in base proto è presente si fa un merge
// 2. se member è una funzione viene semplicemente agganciata
for (member in proto) {
if (proto[member] != null && proto[member].constructor === Object) {
fn[member] = extend(true, {}, base.prototype[member], proto[member]);
} else {
fn[member] = proto[member];
}
}
// bisogna aggiornare sul prototypo di subclass il costruttore che ora punta a base
fn.constructor = subclass;
// per comodita' copio questo metodo, altrimenti dovrei chiamare
// Class.extend.call(ClassePadre,proto);
subclass.extend = that.extend;
return subclass;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment