JavaScript: polimorfismo

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.