2013-06-08 1 views
3

У меня был коллега, спросите меня, почему он не смог получить доступ к параметру события из функции обратного вызова. Оказывается, что jquery, кажется, устанавливает событие в null после завершения вызова, и создание временной локальной переменной устраняет проблему (см. Ниже).Почему переменные внутри функций видимы для функций обратного вызова, объявленных внутри этой функции?

Тогда это заставило меня задуматься, почему «сообщение» доступно даже для обратного вызова. Может кто-нибудь объяснить?

$('some seletor').click({msg: message},function(event){ 
    alert(event.data.msg); //event.data.msg is not available to the json callback because event is null 
    var message = event.data.msg; //message will be available to the callback...why? 
    $.getJSON('ajax/test.json', function(data) { 
     alert(message); //works ok - why is the message variable visible here at all, should it not have gone out of scope when the above function ended? 
     alert(event.data.msg); //will crash, seems that event has been set to null by the framework after the function finished 
    });  
}); 
+2

Из-за закрытия. Подробнее читайте здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures –

+0

+1 для Клауса также (это была ссылка, которую я использовал для ее понимания) – jax

ответ

4

Любая переменная, которая существует в данной области видимости доступен для всех функций, определенных в этой области. (Это как раз то, как область определена для работы в JS, this part of the language specification, вероятно, является хорошей точкой входа, если вы хотите, чтобы она зависела от того, как она определена).

Поскольку выражение функции, определяющее обратный вызов, находится внутри функции, определяющей переменную, переменная доступна для нее.

+0

для других, ссылка, которую дал klaus, лучше понимает закрытие (см. Комментарий на исходный вопрос) – jax

3

Попробуйте это:

$('some seletor').click({msg: message},function(ev){ 
    alert(ev.data.msg); 
    var message = ev.data.msg; 
    $.getJSON('ajax/test.json', function(data) { 
     alert(message); 
     alert(ev.data.msg); 
    });  
}); 

вместо event. Поскольку событие является глобальным объектом window.event, и он становится неопределенным, когда событие заканчивается. Вы можете использовать объект события, не вынимая его из параметра, как это:

$('some seletor').click({msg: message},function(){ 
    alert(event.data.msg); 
}); 
+0

Это не отвечает вопрос. На всех ... –

+0

Я ответил, почему переменная события недоступна. – karaxuna

+0

Хорошо. Впрочем, это был не вопрос. –

0

Если вы прощаете код псевдо - попробуйте думать об этом как вложенные блоки - такого рода вещи

function foo() 
{ 
    int bar=0; 

    //inner block 
    { 
    bar++; 
    } 

} 

или более конкретно

function click() 
{ 
variable {msg: message} 

    //inner block 
    function(ev) 
    { 
    ....  
    } 
} 
Смежные вопросы