2008-10-22 11 views
68

J'essaie de comprendre comment passer des arguments à une fonction anonyme en JavaScript.Comment puis-je transmettre des arguments à des fonctions anonymes en JavaScript?

Vérifiez ce code exemple et je pense que vous verrez ce que je veux dire:

<input type="button" value="Click me" id="myButton" /> 

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 
    var myMessage = "it's working"; 
    myButton.onclick = function(myMessage) { alert(myMessage); }; 
</script> 

En cliquant sur le bouton du message: doit apparaître. Cependant, la variable myMessage à l'intérieur de la fonction anonyme est null.

jQuery utilise beaucoup de fonctions anonymes, quel est le meilleur moyen de transmettre cet argument?

+0

Fermetures: http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html – mishal153

Répondre

62

Votre cas particulier peut simplement être corrigée à travailler:

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 
    var myMessage = "it's working"; 
    myButton.onclick = function() { alert(myMessage); }; 
</script> 

Cet exemple fonctionnera parce que la fonction anonyme créé et attribué en tant que gestionnaire d'élément aura accès à des variables définies dans le contexte où il était créé.

Pour mémoire, un gestionnaire (que vous attribuez à travers la mise onxxx propriété) attend un argument simple de prendre c'est-objet événement étant passé par le DOM, et vous ne pouvez pas forcer le passage autre argument là

9

En supprimant la paramètre de la fonction anonyme sera disponible dans le corps.

myButton.onclick = function() { alert(myMessage); }; 

Pour plus d'informations recherche pour « javascript » fermetures

+0

je besoin de lire sur « fermetures javascript » comme vous l'avez dit .. Merci! – hakksor

22

Ce que vous avez fait ne fonctionne pas parce que vous êtes lier un événement à une fonction. En tant que tel, c'est l'événement qui définit les paramètres qui seront appelés lorsque l'événement est déclenché (c'est-à-dire que JavaScript ne connaît pas votre paramètre dans la fonction que vous avez liée à onclick donc ne peut rien y passer).

Vous pouvez le faire cependant:

<input type="button" value="Click me" id="myButton"/> 

<script type="text/javascript"> 

    var myButton = document.getElementById("myButton"); 

    var myMessage = "it's working"; 

    var myDelegate = function(message) { 
     alert(message); 
    } 

    myButton.onclick = function() { 
     myDelegate(myMessage); 
    }; 

</script> 
+0

Je ne vois pas, comment le message est compris par le lambda qui assigne sa valeur de retour à myDelegate. J'ai vu des lambdas comme fonction (a, b) { // code ici } (a, b); –

0

Qu'est-ce que vous avez fait est créé une nouvelle fonction anonyme qui prend un seul paramètre qui est ensuite affecté à la myMessage variable locale dans la fonction. Comme aucun argument n'est réellement passé, et que les arguments qui ne sont pas passés à une valeur deviennent null, votre fonction ne fait qu'alerte (null).

0

Si vous écrivez comme

myButton.onclick = function() { alert(myMessage); }; 

Il fonctionnera, mais je ne sais pas si cela répond à vos questions.

1

Exemple:

<input type="button" value="Click me" id="myButton"> 
<script> 
    var myButton = document.getElementById("myButton"); 
    var test = "zipzambam"; 
    myButton.onclick = function(eventObject) { 
     if (!eventObject) { 
      eventObject = window.event; 
     } 
     if (!eventObject.target) { 
      eventObject.target = eventObject.srcElement; 
     } 
     alert(eventObject.target); 
     alert(test); 
    }; 
    (function(myMessage) { 
     alert(myMessage); 
    })("Hello"); 
</script> 
+0

Un changement: eventObject = eventObject || window.event; Encore un changement: eventObject = eventObject || window.event || {}; – eyelidlessness

+0

Autre modification: eventObject.target = eventObject.target || eventObject.srcElement || nul; – eyelidlessness

1

Les délégués:

function displayMessage(message, f) 
{ 
    f(message); // execute function "f" with variable "message" 
} 

function alerter(message) 
{ 
    alert(message); 
} 

function writer(message) 
{ 
    document.write(message); 
} 

exécution de la fonction de displayMessage:

function runDelegate() 
{ 
    displayMessage("Hello World!", alerter); // alert message 

    displayMessage("Hello World!", writer); // write message to DOM 
} 
5

Les gestionnaires d'événements attendent un paramètre qui est l'événement qui a été tiré. Vous êtes en train de renommer cela en 'myMessage' et donc vous alertez l'objet événement plutôt que votre message.Une fermeture peut vous permettre de référencer la variable que vous avez définie en dehors de la fonction. Cependant, si vous utilisez Jquery, vous pouvez consulter son API spécifique à l'événement, par exemple.

http://docs.jquery.com/Events/bind#typedatafn

Cela a une option pour passer dans vos propres données.

3
<input type="button" value="Click me" id="myButton" /> 

<script type="text/javascript"> 
    var myButton = document.getElementById("myButton"); 

    myButton.myMessage = "it's working"; 

    myButton.onclick = function() { alert(this.myMessage); }; 


</script> 

Cela fonctionne dans ma suite de tests qui comprend tout de IE6 +. La fonction anonyme est consciente de l'objet auquel elle appartient donc vous pouvez passer les données avec l'objet qui l'appelle (dans ce cas myButton).

20

Ce qui suit est une méthode d'utilisation des fermetures pour résoudre le problème auquel vous faites référence. Il prend également en compte le fait que peut changer le message dans le temps sans affecter la liaison. Et il utilise jQuery pour être succinct.

var msg = (function(message){ 
    var _message = message; 
    return { 
    say:function(){alert(_message)}, 
    change:function(message){_message = message} 
    }; 
})("My Message"); 
$("#myButton").click(msg.say); 
+0

J'apprends. Pourquoi affectez-vous à '_message'? Pourquoi ne pas simplement utiliser 'message'? –

+0

Dans ce cas, je le fais pour que la portée interne de la méthode de changement puisse avoir une signature valide, sinon il n'y aurait aucun moyen de changer la valeur du message dans la fermeture externe. – Gabriel

+0

Grande réponse en utilisant une fermeture. Cependant, je renommerais l'argument de la fonction "change" parce que "message" est trompeur, il devrait être plus clair qu'il n'est pas lié à l'argument externe "message". cette fonction pourrait être refactorisée comme ceci: change: function (newmessage) {_ message = newmessage} –

Questions connexes