Jak mogę przekazać argumenty do anonimowych funkcji w JavaScript?

83

Próbuję dowiedzieć się, jak przekazać argumenty do anonimowej funkcji w JavaScript.

Sprawdź ten przykładowy kod i myślę, że zobaczysz, co mam na myśli:

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

Po kliknięciu przycisku it's workingpowinien pojawić się komunikat :. Jednak myMessagezmienna wewnątrz funkcji anonimowej ma wartość null.

jQuery używa wielu anonimowych funkcji, jaki jest najlepszy sposób przekazania tego argumentu?

hakksor
źródło
Zamknięcia: blog.niftysnippets.org/2008/02/…
mishal153

Odpowiedzi:

72

Twój konkretny przypadek można po prostu poprawić, aby działał:

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

Ten przykład zadziała, ponieważ anonimowa funkcja utworzona i przypisana jako obsługa elementu będzie miała dostęp do zmiennych zdefiniowanych w kontekście, w którym została utworzona.

Dla rekordu program obsługi (przypisany przez ustawienie właściwości onxxx) oczekuje, że pojedynczy argument przyjmie, że jest to obiekt zdarzenia przekazywany przez DOM i nie można wymusić przekazania tam innego argumentu

Sergey Ilinsky
źródło
27

To, co zrobiłeś, nie działa, ponieważ wiążesz zdarzenie z funkcją. W związku z tym jest to zdarzenie, które definiuje parametry, które zostaną wywołane, gdy zdarzenie zostanie wywołane (tj. JavaScript nie wie o parametrze w funkcji, do której jest przypisany onclick, więc nie może nic do niego przekazać).

Możesz to jednak zrobić:

<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
źródło
Nie widzę, jak wiadomość jest rozumiana przez lambdę, która przypisuje jej wartość zwracaną do myDelegate. Widziałem wyrażenia lambda, takie jak function (a, b) {// tutaj kod} (a, b);
Daniel N.
21

Poniżej przedstawiono metodę użycia domknięć w celu rozwiązania problemu, do którego się odnosisz. Uwzględnia również fakt, że może zmienić komunikat w czasie bez wpływu na wiązanie. I używa jQuery do zwięzłości.

var msg = (function(message){
  var _message = message;
  return {
    say:function(){alert(_message)},
    change:function(message){_message = message}
  };
})("My Message");
$("#myButton").click(msg.say);
Gabriel
źródło
Uczę się. Dlaczego przypisujesz do _message? Dlaczego po prostu nie użyć message?
Jonathan M
W tym przypadku robię to tak, aby wewnętrzny zakres metody change mógł mieć prawidłowy podpis, w przeciwnym razie nie byłoby możliwości zmiany wartości wiadomości w zamknięciu zewnętrznym.
Gabriel
Świetna odpowiedź za pomocą zamknięcia. Jednak zmieniłbym nazwę argumentu funkcji „zmień”, ponieważ „komunikat” jest mylący, powinno być wyraźniejsze, że nie jest on powiązany z zewnętrznym argumentem „komunikat”. ta funkcja może być refaktoryzowana w ten sposób: change: function (newmessage) {_ message = newmessage}
Matteo-SoftNet
8

Po usunięciu parametru z funkcji anonimowej będzie dostępna w treści.

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

Aby uzyskać więcej informacji, wyszukaj „zamknięcia javascript”

Aleris
źródło
Musiałem przeczytać o "zamknięciach javascript", jak powiedziałeś .. Dzięki!
hakksor
6

Programy obsługi zdarzeń oczekują jednego parametru, który jest wywołanym zdarzeniem. Tak się składa, że ​​zmieniasz nazwę na „mojaWiadomość” i dlatego ostrzegasz raczej obiekt zdarzenia niż swoją wiadomość.

Zamknięcie może pozwolić ci na odwołanie się do zmiennej, którą zdefiniowałeś poza funkcją, jednak jeśli używasz Jquery, możesz chcieć spojrzeć na jego API specyficzne dla zdarzenia, np.

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

Ma to opcję przekazywania własnych danych.

wioota
źródło
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>

Działa to w moim zestawie testowym, który zawiera wszystko od IE6 +. Funkcja anonimowa jest świadoma obiektu, do którego należy, dlatego możesz przekazać dane z obiektem, który ją wywołuje (w tym przypadku myButton).

Nieznany
źródło
1

Przykład:

<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>
Cień2531
źródło
Jedna zmiana: eventObject = eventObject || window.event; Jeszcze jedna zmiana: eventObject = eventObject || window.event || {};
powiek
Kolejna zmiana: eventObject.target = eventObject.target || eventObject.srcElement || zero;
powiek
1

Delegaci:

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

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

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

Uruchamianie funkcji displayMessage:

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

    displayMessage("Hello World!", writer); // write message to DOM
}
cllpse
źródło
0

To, co zrobiłeś, to utworzenie nowej anonimowej funkcji, która przyjmuje pojedynczy parametr, który jest następnie przypisywany do zmiennej lokalnej myMessage wewnątrz funkcji. Ponieważ w rzeczywistości nie są przekazywane żadne argumenty, a argumenty, które nie mają wartości, stają się zerowe, funkcja po prostu zwraca alert (null).

Ignacio Vazquez-Abrams
źródło
0

Jeśli napiszesz to jak

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

To zadziała, ale nie wiem, czy to odpowiada na twoje pytania.

tpower
źródło