2012-11-08 29 views
23

Ci sono alcune funzioni, questo è qualcosa che funziona a lungo e fornisce callback.Come passare il contesto alla funzione anonima?

someFunc: function(argument, callback, context) { 
    // do something long 

    // call callback function 
    callback(context); 
} 

In applicazione io uso questa funzione

someFunc('bla-bla', function (context) { 
    // do something with this scope 
    context.anotherFunc(); 
}, this); 

Come implementare la funzione di callback senza passare context parametro?

bisogno di un po come questo:

someFunc('bla-bla', function() { 
    // do something with this scope 
    this.anotherFunc(); 
}, this); 
+1

Quindi nel tuo ultimo esempio sembra che tu stia passando il contesto (a qualcosa almeno) sei solo curioso su come fare riferimento all'argomento se non viene chiamato? –

+0

Stai passando il parametro, semplicemente non lo stai usando. E non capisco perché. – bfavaretto

+2

@bfavaretto: OP lo sta usando passandolo nel callback in modo che la callback possa sfruttare i metodi del valore esterno 'this'. Quindi la domanda è come ottenere l'ultimo blocco di codice ... ottenendo il corretto 'this' nel callback in modo che non debba essere passato come argomento. –

risposta

37

La risposta accettata sembra un po 'obsoleta. Supponendo che stai operando su un browser relativamente moderno, puoi utilizzare Function.prototype.bind in vanilla javascript. In alternativa, se si utilizza underscore o jQuery, è possibile utilizzare rispettivamente _.bind o $.proxy (che verrà sostituito a call/apply se necessario).

Ecco una semplice dimostrazione di queste tre opzioni:

// simple function that takes another function 
// as its parameter and then executes it. 
function execute_param(func) { 
    func(); 
} 

// dummy object. providing an alternative context. 
obj = {}; 
obj.data = 10; 

// no context provided 
// outputs 'Window' 
execute_param(function(){ 
    console.log(this); 
}); 

// context provided by js - Function.prototype.bind 
// src: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind 
// outputs 'Object { data=10 }'' 
execute_param(function(){ 
    console.log(this); 
}.bind(obj)); 

// context provided by underscore - _.bind 
// src: http://underscorejs.org/#bind 
// outputs 'Object { data=10 }' 
execute_param(_.bind(function(){ 
    console.log(this); 
},obj)); 

// context provided by jQuery - $.proxy 
// src: http://api.jquery.com/jQuery.proxy/ 
// outputs 'Object { data=10 }' 
execute_param($.proxy(function(){ 
    console.log(this); 
},obj)); 

È possibile trovare il codice in un jsfiddle qui: http://jsfiddle.net/yMm6t/1/ (NOTA: assicuratevi che la console sviluppatore è aperta, o si non si vede qualsiasi uscita)

+0

Sì. Ora sto usando il segno di sottolineatura ovunque :) – acelot

+0

@PiONeeR Sì, anche io :) Potresti voler riconsiderare quale dovrebbe essere la risposta accettata. – EleventyOne

+8

Questa dovrebbe essere la risposta accettata. – Gamak

13

Usa Function.prototype.call per richiamare una funzione e impostare manualmente il valore this di quella funzione.

someFunc: function(argument, callback, context) { 
    callback.call(context); // call the callback and manually set the 'this' 
} 

Ora il callback ha il this valore atteso.

someFunc('bla-bla', function() { 
    // now 'this' is what you'd expect 
    this.anotherFunc(); 
}, this); 

Naturalmente è possibile passare gli argomenti come normale nel .call invocazione.

callback.call(context, argument); 
Problemi correlati