Як я можу передавати аргументи анонімним функціям у 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 використовує багато анонімних функцій, який найкращий спосіб передавати цей аргумент?


Відповіді:


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>

Я не можу зрозуміти, як повідомлення розуміється лямбда, яка присвоює своє повернене значення myDelegate. Я бачив лямбди на зразок функції (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", оскільки "message" вводить в оману, і має бути зрозумілішим, що він не пов'язаний із зовнішнім аргументом "message". цю функцію можна було б відновити таким чином: change: function (newmessage) {_ message = newmessage}
Matteo-SoftNet

9

Видаливши параметр з анонімної функції, вона буде доступна в тілі.

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

Для отримання додаткової інформації шукайте "закриття javascript"


Мені потрібно було прочитати "закриття javascript", як ви сказали. Дякую!
hakksor

5

Обробники подій очікують одного параметра, який є спрацьованою подією. Ви випадково перейменовуєте це на 'myMessage', і тому ви попереджаєте об'єкт події, а не ваше повідомлення.

Закриття може дозволити вам посилатися на змінну, яку ви визначили за межами функції, однак, якщо ви використовуєте Jquery, ви можете захотіти переглянути його API, наприклад

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

Тут є можливість передавати власні дані.


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>

Одна зміна: eventObject = eventObject || window.event; Ще одна зміна: eventObject = eventObject || вікно.захід || {};
безвічність

Ще одна зміна: 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
}

0

Те, що ви зробили, створює нову анонімну функцію, яка приймає один параметр, який потім призначається локальній змінній myMessage всередині функції. Оскільки фактично не передаються аргументи, а аргументи, яким не передано значення, стають нульовими, ваша функція просто оповіщає (null).


0

Якщо ви пишете це як

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

Це спрацює, але я не знаю, чи відповідає це на ваші запитання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.