2010-08-25 6 views
8

Nei miei oggetti JavaScript mi ​​sono trovato a scrivere questo:Esiste un metodo migliore rispetto all'impostazione di una variabile per questo?

this_object = this; 

Sembra che sia l'unico modo per passare variabili membro a funzioni esterne ...

google.maps.event.addListener(this.marker, 'click', function() { 
    this.info_window.setContent('Chicago marker'); 
    this.info_window.open(this.map,this.marker); 
}); 

che non funziona, ho per copiare l'oggetto in una variabile membro e passare il nuovo oggetto (e sostituire tutto this con this_object)

Questo sembra brutto. C'è un modo "migliore" o "più pulito", o è questa la mia unica opzione?

+0

Vedere anche: ['questo' oggetto non è accessibile nelle funzioni JavaScript private senza un trucco?] (Http://stackoverflow.com/questions/3274387/this-object-cant-be-accessed-in- private-javascript-functions-without-a-hack) – CMS

risposta

5

Sicuramente esiste un metodo migliore. Implica la creazione di una funzione con il contesto this già associato a un oggetto particolare.

Per fare in modo che il contesto this si riferisca all'oggetto corrente, chiamare il metodo bind() sulla funzione e passare il contesto richiesto come parametro.

google.maps.event.addListener(this.marker, 'click', function() { 
    this.info_window.setContent('Chicago marker'); 
    this.info_window.open(this.map,this.marker); 
}.bind(this)); // <-- notice we're calling bind() on the function itself 

Questo è ora parte dello standard ECMAScript, e se un browser non implementa in modo nativo, è facile farlo voi stessi.

if (!Function.prototype.bind) { 
    Function.prototype.bind = function() { 
     var fn = this, 
      args = Array.prototype.slice.call(arguments), 
      object = args.shift(); 

     return function() { 
      return fn.apply(
       object, args.concat(Array.prototype.slice.call(arguments)) 
      ); 
     }; 
    }; 
} 

Vedi tutti questions and answers su SO relativi a questo.

+0

sembra simile a un paio di tacche sopra il mio pagamento javascript, ma cercherò di assorbirlo. grazie – Galen

+0

Questo ha il rovescio della medaglia dell'introduzione di una chiamata di funzione extra, ma +1 comunque. –

4

In realtà è un modello piuttosto comune quando si utilizza JavaScript per memorizzare un riferimento di this in una variabile locale, ad esempio var myThing=this;. Ricorda che le funzioni hanno accesso alle variabili locali definite nel loro ambito. Tutte le variabili definite nelle funzioni di contenimento sono accessibili.

0

Ho visto il modello prima (con la variabile in questione chiamata), quindi presumo che sia davvero un comune schema javascript che non ha solo una soluzione più pulita.

0

Non sono sicuro che ciò possa essere d'aiuto per qualsiasi scenario tu abbia a che fare, ma ho trovato che l'utilità evento personalizzata di YUI funziona bene con problemi di scoping con questo e chiusure. È un modello basato sull'evento e un modo di pensare leggermente diverso, ma potrebbe valere la pena di esplorarlo almeno.

http://developer.yahoo.com/yui/event/#customevent

1

Troverete questo pezzo di codice piuttosto frequenti in molte biblioteche e progetti:

function someFunction() { 
    var that = this; 

    //.... 
} 

Ad esempio, si consideri questa funzione:

function container(param) { 

    function dec() { 
     if (secret > 0) { 
      secret -= 1; 
      return true; 
     } else { 
      return false; 
     } 
    } 

    this.member = param; 
    var secret = 3; 
    var that = this; 

    return function() { 
     if (dec()) { 
      return that.member + " " + secret; 
     } else { 
      return null; 
     } 
    }; 
} 

var c = container("foo"); 
alert(c()); // "foo 2"; 
alert(c()); // "foo 1"; 
alert(c()); // "foo 0"; 
alert(c()); // null; 

Read more here.

Problemi correlati