Costruire ed ereditare oggetti JavaScript con i prototipi
In generale, il metodo più rapido per definire oggetti in Javascript è inserire proprietà e metodi direttamente nel costruttore.
Ad esempio, la seguente funzione A() definisce due proprietà e due metodi:
function A() { //costruttore this.p1 = 0; //proprietà 1 this.p2 = ''; //proprietà 2 this.m1 = function() { //metodo 1 }; this.m2 = function() { //metodo 2 }; }
La sintassi per creare ed utilizzare l’oggetto definito sopra è la seguente:
var a = new A(); //creazione dell'oggetto a.p1 = 99; //assegnazione della proprietà p1 a.m2(); //chiamata al metodo m2()
Oggetti JavaScript: diverse varianti
Un approccio alternativo è quello di utilizzare i prototipi per definire le proprietà ed i metodi degli oggetti. Di seguito sono elencate tre varianti di codice Javascript per definire lo stesso oggetto di prima, da preferite a seconda del contesto (e magari anche dei gusti personali…):
Variante 1
Parte dell’oggetto viene definita nel costruttore, e parte nel prototipo
function A() { this.p1 = 0; this.p2 = ''; } A.prototype = { m1: function() { //... } ,m2: function() { //... } };
Variante 2
Proprietà e metodi vengono definiti nel prototipo
function A() { } A.prototype = { p1: 0 ,p2: '' ,m1: function() { //... } ,m2: function() { //... } }
Variante 3
Come la variante 2, ma i metodi vengono definiti con una sintassi differente
function A() { } A.prototype = { p1: 0 ,p2: '' }; A.prototype.m1 = function() { //... }; A.prototype.m2 = function() { //... };
Eredità degli oggetti Javascript
Vediamo infine un esempio per definire un oggetto derivato dal precedente, sempre utilizzando i prototipi.
Attenzione che, usando la variante 1, tutto ciò che è definito all’interno del costruttore (nell’esempio sopra le proprietà p1 e p2 ) non viene ereditato perché non appartiene al prototipo.
function B() { this.__proto__.__proto__ = A.prototype; //eredita il prototipo da A } B.prototype = { _p3: '' //valore di default di p3 ,get p3() { return 'p3 is ' + this._p3; } ,set p3(value) { this._p3 = value.toLowerCase(); } }
Nel prototipo di B sono state aggiunte le keyword get e set per definire le funzioni che vengono chiamate quando si assegna o si legge il valore della proprietà p3.
Sintassi:
var b = new B(); b.m1(); // chiamata del metodo m1 definito in A b.p3 = "PIPPO"; alert(b.p3); // output: p3 is pippo
Nota: questi esempi sono stati verificati in Droidscript.