JavascriptProva

domenica 19 febbraio 2012

Il problema del setInterval con una variabile locale come parametro

Ecco ripassato, con cognizione di causa, il problema che ho avuto in passato con il setInterval.

setInterval è una funzione dell'oggetto window.
Il problema è se io la chiamo da un oggetto diverso fornendole come parametro una variabile dell'oggetto stesso:
<body>
</body>
<script>
function stampa(p){
 document.body.innerHTML+=p;
}
function funzione(){
 this.parola="Ciao, Mondo crudele! ";
 
 setInterval(function(){stampa(this.parola)},2000);
}
f=new funzione();

</script>
Ecco cosa ottengo:
undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined
Perchè?

La spiegazione mi risulta chiara ora che mi sono esercitato un po' sullo scope.
setInterval è una funzione dell'oggetto window. Ora, essendo la proprietà parola non privata, essa è perfettamente visibile dall'oggetto window, ma non viene vista come this. Nel momento in cui la funzione setInterval viene evocata, essa, essendo un metodo dell'oggetto window, riconosce come this l'oggetto window, e non l'oggetto f istanza della funzione funzione.
La soluzione è creare nell'ambito dell'oggetto f una proprietà che detenga il riferimento all'oggetto, da inserire come parametro nella funzione setInterval, in modo che l'oggetto window possa fare il corretto riferimento all'oggetto f e non all'oggetto window.
<body>
</body>
<script>
function stampa(p){
 document.body.innerHTML+=p;
}
function funzione(){
 var questo=this;
 this.parola="Ciao, Mondo crudele! ";
 
 setInterval(function(){stampa(questo.parola)},2000);
}
f=new funzione();

</script>
Il fatto che questo sia una variabile privata non fa nulla perchè essa viene comunque passata nel parametro e quindi resa visibile all'oggetto window.

Ecco:
Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! Ciao, Mondo crudele! 
Avevo già affrontato e risolto questo problema in modo un po' empirico-capronesco, ma adesso lo comprendo molto meglio.

E' bello fare le cose con cognizione di causa!

Nessun commento:

Posta un commento