In JavaScript il concetto di polimorfismo trova la sua più naturale applicazione nella programmazione orientata agli oggetti. Nello specifico, esso indica la capacità di un metodo di essere applicato a più oggetti. JavaScript fornisce due metodi per questo scopo: call() e apply(). Nel nostro esempio vedremo un'applicazione pratica del primo metodo.
Iniziamo col definire un oggetto generico che fungerà da base per gli altri:
function Message(subject) {
this.subject = subject;
this.send = function() {
alert('Message sent!');
}
}
Il metodo send()
sarà appunto il metodo su cui verrà applicato il polimorfismo. Ora creiamo un secondo oggetto che erediterà dal primo e avrà anch'esso lo stesso metodo send()
:
function SMS (){};
SMS.prototype = new Message('Test');
SMS.prototype.constructor = SMS;
SMS.prototype.send = function() {
alert('SMS sent!');
}
Usiamo l'oggetto prototype
per permettere all'oggetto SMS
di ereditare le proprietà e i metodi dell'oggetto Message
associandogli una nuova istanza di Message
. Poi dichiariamo esplicitamente che il costruttore di SMS
non è Message
in modo da separare in tal senso i due oggetti e permettere al nuovo metodo send()
di essere associato solo a SMS
.
A questo punto creiamo un terzo oggetto e specifichiamo anche in questo caso un metodo send()
:
function Email(to) {
this.to = to;
}
Email.prototype.send = function() {
alert('Email sent');
}
Dall'oggetto Email
facciamo derivare un oggetto HTMLEmail
con le stesse modalità viste in precedenza:
function HTMLEmail () {};
HTMLEmail.prototype = new Email('test@localhost');
HTMLEmail.constructor.prototype = HTMLEmail;
In questo caso la sintassi è diversa: abbiamo associato l'oggetto prototype
dell'oggetto constructor
ad HTMLEmail
. In questo modo con prototype
abbiamo accesso anche a Email
e ai suoi membri. Ora possiamo implementare il polimorfismo usando call()
:
HTMLEmail.prototype.send = function() {
alert('[Content-Type: text/html] ');
this.constructor.prototype.send.call(this); // this.constructor.prototype punta a Email
}
Facciamo un semplice test:
window.onload = function() {
var myMessage = new Message('Test');
var mySMS = new SMS();
var myEmail = new Email('test@localhost');
var myHTMLEmail = new HTMLEmail();
var btn1 = document.getElementById('test1');
var btn2 = document.getElementById('test2');
btn1.onclick = function() {
myMessage.send();
mySMS.send();
return false;
};
btn2.onclick = function() {
myEmail.send();
myHTMLEmail.send();
return false;
};
};
Il secondo bottone visualizzerà il seguente alert:
Email sent [Content-Type: text/html] Email sent
Potete visionare l'esempio finale in questa pagina.