2009-08-19 8 views
91

Est-il possible de passer une fonction javascript avec des paramètres en paramètre?Passer une fonction avec des paramètres en paramètre?

Exemple:

$(edit_link).click(changeViewMode(myvar)); 
+4

Il ressemble à JQuery, et le plus probable est, mais qui est hors de propos.L'utilisation ou les paramètres et les fonctions sont les mêmes quelles que soient les bibliothèques Javascript que vous utilisez. – Guffa

+0

@Guffa - Je me demandais si elle devrait être étiqueté avec jQuery –

+1

@Lucia S'il vous plaît envisager de changer la réponse acceptée à [this] (http://stackoverflow.com/a/34567019/3853934). –

Répondre

175

Utilisez une « fermeture »:

$(edit_link).click(function(){ return changeViewMode(myvar); }); 

Cela crée une enveloppe de fonction temporaire anonyme qui connaît sur le paramètre et il passe à la mise en œuvre de rappel en cours.

+2

Si vous souhaitez appeler une fonction sur un objet, vous devez appeler bind(). myObj.click (function() {this.doSomething();} .bind (myObj)); Cela fera que "ceci" soit myObj. – Eli

+0

N'est-ce pas un problème de performance lorsqu'il s'agit de beaucoup de ceux-ci? Par exemple. Vous rendez un onPress dans une rangée et vous avez 10 000 lignes. Cela crée un nouveau wrapper de fonction temporaire anonyme pour chaque ligne. Y a-t-il un autre moyen de le faire? –

+0

@JoshuaPinter La technique elle-même n'est pas un problème. Si vous avez besoin de la même fonction appeler 10 000 fois, vous pouvez simplement enregistrer l'encapsuleur dans une variable, de sorte que vous ne le créez qu'une seule fois. Si vous devez passer 10 000 contextes différents, vous ne pouvez pas faire grand-chose. Attention à l'optimisation prématurée: Comme toujours avec les performances, vous devez * mesurer * pour voir s'il y a un problème ou non. Les moteurs JavaScript d'aujourd'hui sont très puissants et pourraient optimiser le code de manière surprenante. –

8

Oui, comme ceci:

$(edit_link).click(function() { changeViewMode(myvar) }); 
14

Non, mais vous pouvez passer un sans paramètres, et faire ceci:

$(edit_link).click(
    function() { changeViewMode(myvar); } 
); 

Donc vous passez une fonction anonyme sans paramètre, que fonction appelle alors votre fonction paramétrée avec la variable dans la fermeture

29

Utilisez Function.prototype.bind(). Citant MDN:

Le bind() procédé crée une nouvelle fonction qui, lorsqu'elle est appelée, a son mot this réglé sur la valeur fournie, avec une séquence donnée d'arguments précédents quelconque pourvu que la nouvelle fonction est appelée.

Il est pris en charge par tous les principaux navigateurs, y compris IE9 +.

Votre code devrait ressembler à ceci:

$(edit_link).click(changeViewMode.bind(null, myvar)); 

Side note: Je suppose que vous êtes dans le contexte mondial, à savoir la variable this est window; sinon, utilisez this au lieu de null.

+0

Merci, cela m'a aidé. Utilisé comme ceci: '$ .ajax (url) .done (handler.bind (this, var1, var2));' – Thomas

+1

Quelle option est la meilleure? Utiliser la fermeture ou utiliser la fonction de liaison? S'il vous plaît laissez-moi savoir s'il y a un impact sur les performances – Varun

+3

@Varun Voir [Pourquoi bind est-il plus lent qu'une fermeture?] (Http://stackoverflow.com/questions/17638305/why-is-bind-slower-than-a-closure) –

2

Vous pouvez le faire

var message = 'Hello World'; 

var callback = function(){ 
alert(this) 
}.bind(message); 

puis

function activate(callback){ 
    callback && callback(); 
} 

activate(callback); 

Ou si votre rappel contient une logique plus souple que vous pouvez passer l'objet.

Demo

1

Voici un exemple suivant l'approche de Ferdinand Beyer:

function function1() 
{ 
    function2(function() { function3("parameter value"); }); 
} 
function function2(functionToBindOnClick) 
{ 
    $(".myButton").click(functionToBindOnClick); 
} 
function function3(message) { alert(message); } 

Dans cet exemple, la « valeur du paramètre » est passé de function1 à FUNCTION3 par fonction2 à l'aide d'une enveloppe de fonction.

0

Ou si vous utilisez ES6, vous devriez être en mesure d'utiliser une fonction de flèche

$(edit_link).click(() => changeViewMode(myvar)); 
Questions connexes