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:
undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedPerchè?
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