sabato, novembre 22, 2014

"this" questo sconosciuto

Uno dei problemi principali che un programmatore java affronta nello studiare javascript, è capire a cosa punta il benedetto reference this.

In java è semplice, ho una classe con proprietà e metodi, istanzio un oggetto di quella classe, this rappresenta l'oggetto istanziato su cui si invocano i metodi.

In javascript non è così ovvio.

Nel contesto globale, this rappresenta l'oggetto globale window


 <script>  
   var f = function() {  
          console.log(this);  
        };  
      f();  
 </script>  

In una funzione costruttore, che deve essere invocata con l'operatore new, this rappresenta l'oggetto che verrà creato e restituito al termine dell'esecuzione della funzione stessa.

 var Auto = function(colore, cilindrata) {  
           this.colore = colore;  
           this.cilindrata = cilindrata;  
          };  
   
 var ferrari = new Auto("rossa", 6000);  

Ma provate a dimenticarvi dell'operatore new, inaspettatamente this ritorna a puntare a window.

Se dichiarate un oggetto con una proprietà di tipo funzione, tale funzione viene chiamata metodo dell'oggetto e this punta all'oggetto stesso.

 var auto = {  
    colore : "rosso",  
    cilindrata: 1500,  
    motore: "spento",  
    accendi: function() {  
             this.motore = "acceso";  
           },  
    spegni: function() {  
            this.motore = "spento";  
          }  
 };  

Provate ad omettere this nei corpi delle funzioni, vi ritroverete con una nuova proprietà motore nell'oggetto globale window, senza alcun tipo di errore in fase di esecuzione.

Fin qui, tutto sommato ce la caviamo, date un'occhiata al prossimo esempio e provate a capire a cosa punta this

 var esempio = {  
     nome: "ivan",  
     metodo: function() {  
              function inner() {  
               alert(this.nome);  
              }  
             alert(this.nome);  
             inner();  
            }  
 };  

Metodo è una proprietà dell'oggetto esempio, di tipo funzione, quindi this punta all'oggetto stesso, l'alert della funzione esterna stampa "ivan".

Nella funzione metodo, è definita una funzione interna (inner function), sarebbe molto naturale credere che il this della inner function punti allo stesso oggetto esempio, ma non è così.

Le inner function non ricevono il valore this dall'outer function.

Invocando inner(), l'alert della inner function stampa "undefined", perchè this punta a window nella inner function.

Per ovviare a questo problema, sfruttando il concetto di closure, l'esempio precedente lo riscriviamo in questo modo:

 var esempio = {  
     nome: "ivan",  
     metodo: function() {  
              var that = this;  
              function inner() {  
               alert(that.nome);  
              }  
             alert(this.nome);  
             inner();  
            }  
 };  

Memorizziamo il valore this in una varibile locale that, poichè le inner function hanno accesso alle varibili locali delle outer tramite il meccanismo delle closure, questa volta anche il secondo alert stamperà, come voluto, il valore "ivan".

Spero che ora, non abbiate piu' dubbi nell'affrontare i vari this e that :)

Alla prox.
Ivan


Nessun commento:

Posta un commento