2012-10-31 13 views
6

Qualcosa mi ha sempre infastidito dal modo in cui eseguo la codifica orientata agli oggetti in Javascript. Quando c'è un callback, ho spesso voglia di fare riferimento all'oggetto che ha chiesto in origine la funzione, che mi porta a fare qualcosa di simile:Fare riferimento a "questo" all'interno di una javascript callback

MyClass.prototype.doSomething = function(obj, callback) { 
    var me = this; // ugh 
    obj.loadSomething(function(err, result) { 
     me.data = result; // ugh 
     callback(null, me); 
    }); 
} 

Prima di tutto, creando la variabile aggiuntiva sempre puntuale sembrava ... eccessivo per me. Inoltre, mi chiedo se potrebbe finire per causare problemi (riferimenti circolari? Oggetti non-GCd?) Passando la variabile "me" al callback.

C'è un modo migliore per andare su questo? Questo approccio è malvagio?

+1

'questo' non è una variabile. "questo" non può essere chiuso. L'approccio va bene. –

+1

Il FUD su "male" ed "eccessivo" mi infastidisce. Va bene non gradire il boilerplate ma perché inventare problemi immaginari con esso? È necessario mantenere un riferimento agli stessi dati allegati, indipendentemente dall'approccio utilizzato, poiché la funzione interna non cambia. Se manterrai solo un riferimento al minor numero di dati necessario è qualcosa di cui l'interprete dovrebbe preoccuparsi. – millimoose

+0

@millimoose Ben detto: non sono riuscito a trovare un modo per riassumere quell'ultima riga. (E ancora mi imbatto in "male" - beh, non "male", ma veramente terribile in un modo molto oggettivo - codice che usa 'nuova funzione (" .. ")' per "evitare problemi".) –

risposta

8

Questo è ciò che Function.bind() è per:

MyClass.prototype.doSomething = function(obj, callback) { 
    obj.loadSomething((function(err, result) { 
     this.data = result; 
     callback(null, this); 
    }).bind(this)); 
} 
+3

Potrebbe voler cambiare 'me' a' this' – Shmiddty

+0

@ Schmiddty Whoops, buona presa. – millimoose

+0

+1 per la buona risposta, risposta accettata per il collegamento della documentazione. –

7

AFAIK, quello che stai facendo è lo schema accettato per questo genere di cose e non causa alcun problema. Molte persone usano "sé" o "quello" come riferimento memorizzato - il "sé" può essere più intuitivo se si proviene da uno sfondo pitone.

+2

Mi piace 'self'. Tuttavia, * è * anche 'window.self' .. anche se non ho mai incontrato confusione sul problema. –

+0

E a volte può essere confuso con [window.self] (https://developer.mozilla.org/en-US/docs/DOM/window.self) – epascarello

3

Questo è un comportamento normale per JavaScript. Il contesto per this è stato modificato per l'oggetto loadSomething e il motivo per cui si dispone della richiamata consiste nell'acquisire riferimenti di chiusura come la variabile me.

3

È possibile associare questo al campo di applicazione della funzione interna

MyClass.prototype.doSomething = function(obj, callback) { 
    obj.loadSomething(function(err, result) { 
     this.data = result; 
     callback(null, this); 
    }.bind(this)); 
} 
1

Questo è il modo più comune che ho visto per gestire la cosa, ho di solito uso var auto = this ;, ma è solo un nome. Anche se è una variabile extra, considerando il sovraccarico di javascript e il fatto che non duplica l'oggetto, non avrà alcun impatto sulle prestazioni.

Problemi correlati