JavaScript, come già sappiamo, considera tutto come un oggetto e quindi rappresenta in questo modo anche le funzioni (e quindi i metodi). Ciascuna funzione presenta infatti proprietà e metodi proprio come un normale oggetto.
Il prototipo dell'oggetto Function presenta due metodi di fondamentale importanza che sono apply()
e call()
. Il loro comportamento è simile, presentano una semplice differenza nella gestione dei parametri. Essi permettono infatti di invocare una determinata funzione definendo quale sarà il suo scope passandoglielo come primo parametro. È possibile inoltre fornire ulteriori parametri che verranno in qualche modo "passati" alla funzione oggetto dell'invocazione.
La differenza tra apply e call è proprio questa: apply()
oltre all'oggetto scope accetta un vettore di parametri, mentre call()
accetta un numero indefinito di parametri. Passiamo all'esempio:
<script type="text/javascript">
var persona = {
nome: "Alberto",
eta: 25
}
var cane = {
nome: "Pluto",
eta: 4
}
function stampaNomeEdEta(moltiplicatore) {
if(!moltiplicatore) moltiplicatore = 1;
alert(this.nome + ":n" + (this.eta*moltiplicatore) + " anni");
}
stampaNomeEdEta.call(persona);
// un anno di un cane corrisponde a sette anni uomo giusto??
stampaNomeEdEta.call(cane, 7);
</script>
In questo esempio è possibile vedere come la stessa funzione stampaNomeEdEta(moltiplicatore)
, venga invocata su diversi oggetti senza essere in qualche modo assegnata ad essi sotto forma di un metodo. Da notare nel primo caso l'assegnazione di 1 a moltiplicatore come valore di default.
Una volta capito questo semplice meccanismo possiamo quindi ritornare al nostro problema di prima e sostituire il window.onload()
in questo modo:
window.onload = function() {
document.getElementsByTagName("button")[0].onclick = persona.stampaNomeCognome.call(persona);
}
Niente di più sbagliato! Dobbiamo assegnare una funzione all'evento onclick
, non eseguirla. In questo caso infatti l'utilizzo del metodo call()
(o del metodo apply()
) è errato in quanto esso esegue subito la funzione.
apply()
e call()
in questo caso allora non bastano, abbiamo bisogno di qualche altra struttura più complessa; struttura che non è presente di default in JavaScript ma che dobbiamo crearci noi.