Wie kann ich in JavaScript Argumente an anonyme Funktionen übergeben?

83

Ich versuche herauszufinden, wie Argumente an eine anonyme Funktion in JavaScript übergeben werden.

Schauen Sie sich diesen Beispielcode an und ich denke, Sie werden sehen, was ich meine:

<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>

Wenn Sie auf die Schaltfläche klicken, sollte die Meldung: it's workingangezeigt werden. Die myMessageVariable in der anonymen Funktion ist jedoch null.

jQuery verwendet viele anonyme Funktionen. Wie kann dieses Argument am besten übergeben werden?

Hakksor
quelle
Schließungen
mishal153

Antworten:

72

Ihr spezieller Fall kann einfach so korrigiert werden, dass er funktioniert:

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

Dieses Beispiel funktioniert, weil die anonyme Funktion, die als Handler für das Element erstellt und zugewiesen wurde, Zugriff auf Variablen hat, die in dem Kontext definiert sind, in dem sie erstellt wurde.

Für den Datensatz erwartet ein Handler (den Sie durch Festlegen der Eigenschaft onxxx zuweisen), dass ein einzelnes Argument verwendet wird, dh ein Ereignisobjekt, das vom DOM übergeben wird, und Sie können die Übergabe eines anderen Arguments dort nicht erzwingen

Sergey Ilinsky
quelle
27

Was Sie getan haben, funktioniert nicht, weil Sie ein Ereignis an eine Funktion binden. Als solches ist es das Ereignis, das die Parameter definiert, die aufgerufen werden, wenn das Ereignis ausgelöst wird (dh JavaScript kennt Ihren Parameter in der Funktion, die Sie an einen Klick gebunden haben, nicht und kann daher nichts an ihn übergeben).

Sie könnten dies jedoch tun:

<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>
jmcd
quelle
Ich kann nicht sehen, wie die Nachricht vom Lambda verstanden wird, das myDelegate seinen Rückgabewert zuweist. Ich habe Lambdas wie Funktion (a, b) gesehen {// Code hier} (a, b);
Daniel N.
21

Im Folgenden finden Sie eine Methode zur Verwendung von Abschlüssen, um das Problem zu beheben, auf das Sie sich beziehen. Es berücksichtigt auch die Tatsache, dass die Nachricht im Laufe der Zeit geändert werden kann, ohne die Bindung zu beeinträchtigen. Und es verwendet jQuery, um kurz zu sein.

var msg = (function(message){
  var _message = message;
  return {
    say:function(){alert(_message)},
    change:function(message){_message = message}
  };
})("My Message");
$("#myButton").click(msg.say);
Gabriel
quelle
Ich lerne. Warum ordnen Sie zu _message? Warum nicht einfach benutzen message?
Jonathan M
In diesem Fall mache ich das so, dass der innere Bereich der Änderungsmethode eine gültige Signatur haben kann, andernfalls gibt es keine Möglichkeit, den Nachrichtenwert im äußeren Abschluss zu ändern.
Gabriel
Tolle Antwort mit einem Verschluss. Ich würde jedoch das Funktionsargument "change" umbenennen, da "message" irreführend ist. Es sollte klarer sein, dass es nicht mit dem äußeren Argument "message" zusammenhängt. Diese Funktion könnte folgendermaßen überarbeitet werden: change: function (newmessage) {_ message = newmessage}
Matteo-SoftNet
9

Durch Entfernen des Parameters aus der anonymen Funktion wird im Körper verfügbar.

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

Für weitere Informationen suchen Sie nach 'Javascript-Verschlüssen'

Aleris
quelle
Ich musste mich über "Javascript-Verschlüsse" informieren, wie Sie sagten. Danke!
Hakksor
5

Ereignishandler erwarten einen Parameter, nämlich das Ereignis, das ausgelöst wurde. Sie benennen das zufällig in "myMessage" um und alarmieren daher eher das Ereignisobjekt als Ihre Nachricht.

Mit einem Abschluss können Sie auf die Variable verweisen, die Sie außerhalb der Funktion definiert haben. Wenn Sie jedoch Jquery verwenden, sollten Sie sich die ereignisspezifische API ansehen, z

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

Dies hat die Möglichkeit, Ihre eigenen Daten weiterzugeben.

wioota
quelle
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>

Dies funktioniert in meiner Testsuite, die alles von IE6 + enthält. Die anonyme Funktion kennt das Objekt, zu dem sie gehört, daher können Sie Daten mit dem Objekt übergeben, das sie aufruft (in diesem Fall myButton).

Unbekannt
quelle
1

Beispiel:

<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>
Shadow2531
quelle
Eine Änderung: eventObject = eventObject || window.event; Noch eine Änderung: eventObject = eventObject || window.event || {};
Augenlidlosigkeit
Eine weitere Änderung: eventObject.target = eventObject.target || eventObject.srcElement || Null;
Augenlidlosigkeit
1

Die Delegierten:

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

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

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

Ausführen der Funktion displayMessage:

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

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

Sie haben eine neue anonyme Funktion erstellt, die einen einzelnen Parameter verwendet, der dann der lokalen Variablen myMessage innerhalb der Funktion zugewiesen wird. Da tatsächlich keine Argumente übergeben werden und Argumente, denen kein Wert übergeben wird, null werden, gibt Ihre Funktion nur alert (null) aus.

Ignacio Vazquez-Abrams
quelle
0

Wenn du es so schreibst

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

Es wird funktionieren, aber ich weiß nicht, ob das Ihre Fragen beantwortet.

tpower
quelle