Как передать аргументы анонимным функциям в JavaScript?

83

Я пытаюсь понять, как передать аргументы анонимной функции в JavaScript.

Посмотрите этот пример кода, и я думаю, вы поймете, что я имею в виду:

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

При нажатии на кнопку it's workingдолжно появиться сообщение: Однако myMessageпеременная внутри анонимной функции равна нулю.

jQuery использует множество анонимных функций, как лучше всего передать этот аргумент?

Хакксор
источник
Закрытие: blog.niftysnippets.org/2008/02/…
mishal153,

Ответы:

72

Ваш конкретный случай можно просто исправить, чтобы он работал:

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

Этот пример будет работать, потому что анонимная функция, созданная и назначенная в качестве обработчика для элемента, будет иметь доступ к переменным, определенным в контексте, в котором она была создана.

Для записи обработчик (который вы назначаете через настройку свойства onxxx) ожидает, что один аргумент будет принимать объект события, передаваемый DOM, и вы не можете принудительно передать туда другой аргумент.

Сергей Ильинский
источник
27

То, что вы сделали, не работает, потому что вы привязываете событие к функции. Таким образом, это событие, которое определяет параметры, которые будут вызываться при возникновении события (т.е. JavaScript не знает о вашем параметре в функции, которую вы связали с onclick, поэтому не может ничего передать в него).

Однако вы можете сделать это:

<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
источник
Я не могу понять, как сообщение понимает лямбда, которая присваивает его возвращаемое значение myDelegate. Я видел лямбды вроде function (a, b) {// здесь код} (a, b);
Дэниел Н.
21

Ниже приводится метод использования замыканий для решения проблемы, на которую вы ссылаетесь. Он также принимает во внимание тот факт, что со временем сообщение может быть изменено, не влияя на привязку. И для краткости он использует jQuery.

var msg = (function(message){
  var _message = message;
  return {
    say:function(){alert(_message)},
    change:function(message){_message = message}
  };
})("My Message");
$("#myButton").click(msg.say);
Габриэль
источник
Я изучаю. Почему вы назначаете _message? Почему бы просто не использовать message?
Джонатан М.
В этом случае я делаю это для того, чтобы внутренняя область действия метода изменения могла иметь действительную подпись, иначе не было бы возможности изменить значение сообщения во внешнем замыкании.
Габриэль
Отличный ответ с использованием закрытия. Однако я бы переименовал аргумент функции «изменить», потому что «сообщение» вводит в заблуждение, должно быть более ясно, что оно не связано с внешним аргументом «сообщение». эту функцию можно реорганизовать следующим образом: change: function (newmessage) {_ message = newmessage}
Matteo-SoftNet
8

После удаления параметра анонимная функция будет доступна в теле.

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

Для получения дополнительной информации выполните поиск по запросу «закрытие JavaScript».

Aleris
источник
Мне нужно было прочитать о "закрытии javascript", как вы сказали ... Спасибо!
hakksor
6

Обработчики событий ожидают один параметр, который является инициированным событием. Вы случайно переименовали это в myMessage и, следовательно, предупреждали объект события, а не свое сообщение.

Замыкание может позволить вам ссылаться на переменную, которую вы определили вне функции, однако, если вы используете JQuery, вы можете захотеть взглянуть на его API для конкретного события, например

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

У этого есть возможность передачи ваших собственных данных.

Wioota
источник
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>

Это работает в моем тестовом наборе, который включает все, начиная с IE6 +. Анонимная функция знает об объекте, которому она принадлежит, поэтому вы можете передавать данные с помощью вызывающего ее объекта (в данном случае myButton).

Неизвестно
источник
1

Пример:

<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>
Тень2531
источник
Одно изменение: eventObject = eventObject || window.event; Еще одно изменение: eventObject = eventObject || window.event || {};
век
Еще одно изменение: eventObject.target = eventObject.target || eventObject.srcElement || ноль;
век
1

Делегаты:

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

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

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

Запуск функции displayMessage:

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

    displayMessage("Hello World!", writer); // write message to DOM
}
cllpse
источник
0

Вы создали новую анонимную функцию, которая принимает единственный параметр, который затем присваивается локальной переменной myMessage внутри функции. Поскольку на самом деле аргументы не передаются, а аргументы, которым не было передано значение, становятся нулевыми, ваша функция просто выдает предупреждение (null).

Игнасио Васкес-Абрамс
источник
0

Если вы напишете это как

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

Это сработает, но я не знаю, отвечает ли это на ваши вопросы.

tpower
источник