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.