2010-02-12 20 views
7

ho una classe JavaScript che assomiglia a questo:Ambito di "questo" in JavaScript

function SomeFunction() 
{ 
    this.doSomething(function() 
    { 
     this.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Questo codice genera un errore perché la portata di "questo" all'interno della funzione che viene passata in doSomething() è diverso da quello di "questo" al di fuori di quella funzione.

Capisco perché questo è, ma qual è il modo migliore per affrontare questo? Questo è quello che finisco per fare:

function SomeFunction() 
{ 
    var thisObject = this; 

    this.doSomething(function() 
    { 
     thisObject.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Che funziona bene, ma sembra proprio un hack. Mi chiedo solo se qualcuno ha un modo migliore.

+2

@Jon Kruger Questo è quello che faccio anch'io. Penso che sia abbastanza normale. Puoi cambiare 'this' con' call' e 'apply', ma non sempre ciò che stai facendo bene. Un'altra opzione sta passando a 'this' come parametro, ma questo sembra ancora di più di un hack. –

+0

@ Jonathon Cosa intendi con "Puoi cambiare questo con call e apply"? –

+1

@Jon Kruger Vedi questo, controlla anche il loro articolo per 'call': https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply –

risposta

10

Questa è la soluzione corretta e comunemente accettata. È un po 'scialbo ma è quello che fanno tutti. In genere questa variabile supplementare è chiamato self, come in:

function SomeFunction() 
{ 
    var self = this; 

    this.doSomething(function() 
    { 
     self.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 
+1

Si noti che 'self' è una proprietà dell'oggetto window nei browser che punta su se stesso, anche se è improbabile che ciò possa causare problemi. –

+0

Altri nomi che ho visto usati un po 'sono 'that' e' me', a seconda del contesto. – cHao

3

this ha dinamica "scope". Ciò significa che è impostato da qualunque cosa lo leghi, e this è associato a una "chiamata di metodo". Cioè, qualsiasi tempo nel vostro programma è visibile: w.f() poi mentre f viene eseguita, this è dinamicamente legato a f, anche sef avuto this nel suo ambito lessicale.

La maggior parte dei framework JavaScript fornisce alcuni servizi per risolvere questo problema esatto. Con Prototype.js (per esempio) si può fare questo:

this.doSomething(function() { this.doSomethingElse(); }.bind(this)); 

Il tuo "hack", tuttavia, è bene. Di solito faccio un (function (self) { ... })(this) attorno a qualsiasi funzione di cui ho bisogno con una variabile di tipo this con scope.

1

Vale anche la pena ricordare che la prossima versione di ECMAScript (la specifica del linguaggio per JavaScript) introdurrà Function.bind(), che ti consentirà di specificare un contesto permanente per una funzione.

Problemi correlati