Uno degli aspetti più confusi di jQuery è come assegna l’ambito durante il callback. Deve essere parecchio confuso perché l’argomento genera un sacco di domande sulla mailing list di jQuery. Peccato, davvero, perché jQuery imposta l’ambito al fine di semplificare il nostro codice e non per renderlo più confuso.
Ecco alcune indicazioni che possono aiutare a ricordare di cosa si tratta la parola this.

this è un elemento DOM

Quando this è un elemento DOM? La risposta breve è – di solito. Lo scripting con jQuery molto spesso comporta l’uso di funzioni di callback. Nella gestione di un evento, o iterando un insieme di nodi, nell’animare un’immagine, o nell’applicazione di un filtro dinamico, le funzioni di richiamate (o callback) sono utilizzate per invocare il codice personalizzato al momento opportuno. Per rendere le cose facili per te, jQuery imposta l’ambito della funzione di callback all’elemento che costituisce l’oggetto della richiamata. Per esempio, quando si vuole gestire un evento clic del mouse per un elemento, si associa una funzione per gestire l’evento in questo modo:
Copia codice

$('#myButton').bind('click', function() {
   // il nostro codice per gestire l'evento
   // si trova qui, nella funzione di callback
});
Quando un utente fa clic sull’elemento ‘myButton’, jQuery invoca la funzione di callback che è stato passato al metodo bind. Ma quando s’invoca nostro callback si definisce l’ambito corrente all’elemento DOM che ha avviato l’evento, in questo caso l’elemento ‘myButton’. jQuery lo fa per comodità. L’oggetto che ha più probabilità di essere richiamato dall’evento in callback è l’elemento che ha generato l’evento. E quale modo più facile per avere accesso a esso utilizzando la parola chiave this? Così all’interno della funzione di callback si può presumere che this è l’elemento rilevante DOM:
Copia codice

$('#myButton').bind('click', function() {
   // 'this' è  l'elemento DOM che ha attivato l'evento
   alert(this.id == 'myButton');
});
Diamo un’occhiata a quanto spesso this è un elemento DOM quando si utilizza jQuery. Abbiamo appena visto il caso di un gestore di eventi, qui sono alcuni altri:
Elementi d’iterazione con il metodo each:
Copia codice

$('div').each(function() {
   // 'this' è  un elemento DOM
   alert(this.tagName.toLowerCase() == 'div');
});
Usando il metodo load di AJAX:
Copia codice

$('#myDiv').load('myUrl.php', function() {
   // 'this' è  un elemento DOM
   alert(this.id == 'myDiv');
});
Usando animazione:
Copia codice

$('#myDiv').fadeOut('slow', function() {
   // 'this' è  un elemento DOM
   alert(this.id == 'myDiv');
});
Utilizzando filtri di selezione:
Copia codice

var set = $('div').filter(function() {
   // 'this' è  l'elemento DOM
   alert(this.tagName.toLowerCase() == 'div');
   return true;
});
Usando il costruttore “document ready”:
Copia codice

$(document).ready(function() {
   // 'this' è  l'oggetto del documento
   alert(this === document);
});
Usando eventi globali AJAX:
Copia codice

$().ajaxStart(function() {
   // 'this' è  l'oggetto del documento
   alert(this === document);
});
Quest’ultimo potrebbe confondere. Perché this è l’oggetto del documento nella richiamata ajaxStart? I metodi che avvolgono le funzioni di callback per gli eventi globali AJAX sono metodi vincolanti. Questi si legano al gestore di eventi di un elemento DOM. Quando l’evento avviene, il gestore è chiamato, nel contesto dell’elemento DOM. E quando si utilizza la funzione dollaro con jQuery senza argomenti, utilizza implicitamente l’oggetto documento come l’elemento selezionato. Quindi un altro modo di scrivere lo snippet del codice precedente è il seguente:
Copia codice

$(document).bind('ajaxStart', function() {
   alert(this == document);
});
Ora probabilmente si può vedere come this è determinato da come si chiamano i metodi AJAX vincolanti:
Copia codice

$(window).ajaxStart(function() {
   alert(this == window);
});
$('#busyIndicator').ajaxStop(function() {
   alert(this.id == 'busyIndicator');
});
$('div.error').ajaxError(function() {
   alert(this.tagName.toLowerCase() == 'div');
});
this è un oggetto
Come menzionato prima, quando si cicla degli elementi con l’iteratore each di jQuery, this è sempre un elemento DOM. Tecnicamente, è più esatto dire che all’interno di un’iterazione each, this è il soggetto del ciclo nell’iterazione corrente. Questa distinzione è importante perché il metodo each di jQuery può essere utilizzato per scorrere su qualsiasi tipo di oggetti array e non solo Liste di nodi.
Copia codice

var arr = ['a','b','c'];
$.each(arr, function(index, obj) {
   // 'this' è  l'oggetto dell'iterazione corrente
   alert(this.constructor == String);
   alert(arr[index] == this);
   alert(this == obj);
});
// o utilizzando una sintassi diversa
// ma funzionalmente equivalenti:
$(arr).each(function(index, obj) {
   // 'this' è  l'oggetto dell'iterazione corrente
   alert(this.constructor == String);
   alert(arr[index] == this);
   alert(this == obj);
});
this è un oggetto jQuery
Prendete nota autori dei plugin! Se avete scritto un plugin le cui funzionalità possono essere applicate a molti elementi, allora molto probabilmente l’avete fatto utilizzando l’estensione standard fn:
Copia codice

$.fn.myPlugin = function() {
   // il vostro codice del plugin va qui!
});
All’interno della vostra funzione del plugin this è l’oggetto jQuery. E se si rispettano le linee guida del Plugin Authoring, il metodo del plugin restituisce sempre this al fine di mantenere Chainability.
Copia codice

$.fn.myPlugin = function() {
   // 'this' è  l'oggetto jQuery
   alert("jQuery version: " + this.jquery);
   return this;
});
Tipicamente, un plugin funziona su ogni elemento DOM che è stato selezionato dall’oggetto jQuery. In poche parole, ciò significa usare il metodo each all’interno di ogni plugin. Troverete spesso questa tecnica implementata nel seguente modo:
Copia codice

$.fn.myPlugin = function() {
   // 'this' è  l'oggetto jQuery
   alert("jQuery version: " + this.jquery);
   return this.each(function() {
  // 'this' è  ora l'elemento DOM
  // come soggetto dell'iterazione 'each'
  alert("current element: " + this.tagName);
   });
});
this è un oggetto AJAX per impostazioni
Ho accennato prima sul metodo load di jQuery e le funzioni di callback per gli eventi globali AJAX. Quelle richiamate sono legate specificamente a un elemento del DOM o a un insieme di elementi. Il resto dei metodi AJAX, $.get, $.post, $.ajax, ecc, operano al di fuori del contesto di un insieme specifico dell’elemento. Ma questi metodi possono essere passati con le funzioni di callback per cui è importante capire che this è in quelle richiamate. Fortunatamente, tutto quello che si deve ricordare è che per ciascuna delle funzioni di callback locale AJAX, beforeSend, success, complete, e error, this è sempre uguale alle impostazioni dell’oggetto utilizzato per la chiamata AJAX.
Copia codice

$.get('myUrl', function() {
   // 'this' è  l'oggetto  AJAX per le
   // impostazioni usato per ottenere la chiamata
   alert(this.url == 'myUrl');
});
$.ajax({
   type: 'POST',
   url: 'myUrl',
   timeout: 5000,
   beforeSend: function() {
  alert(this.url == 'myUrl');
   },
   error: function() {
  alert(this.timeout == 5000);
   },
   success: function() {
  alert(this.type == 'POST');
   },
   complete: function() {
  alert(this.async == true);
   }
});
Conversione da this a $this
Quando this è un elemento DOM che spesso è nel contesto del codice che ha bisogno di accedere o manipolare in qualche modo. Quindi, come possiamo utilizzare la potenza delle API jQuery quando this è un elemento DOM? Questo, naturalmente, è qualcosa che eccelle in jQuery. Basta trasformare this in $this:
Copia codice

$('div').each(function() {
   // 'this' è  un elemento DOM
   // avvolgere 'this' in un oggetto jQuery
   var $this = $(this);
   // ora abbiamo l'API jQuery a nostra disposizione
   var title = $this.attr("title");
   if (title != null) {
  $this.prepend("<h2>" + title + "</h2>");
   }
});
Quando siete confusi su cosa è this all’interno di un blocco di un dato codice, chiedetevi: “Che cosa ha più senso qui?” Molto spesso, la risposta a questa domanda è uguale a this.