Javascript 为什么函数中的变量对该函数中声明的回调函数可见?

Javascript 为什么函数中的变量对该函数中声明的回调函数可见?,javascript,jquery,Javascript,Jquery,我有一位同事问我为什么他不能从回调函数中访问事件参数。结果表明,jquery似乎在调用完成后将事件设置为null,并创建了一个临时局部变量来修复问题(见下文) 然后,这让我思考,为什么“消息”甚至可以用于回调。有人能解释一下吗 $('some seletor').click({msg: message},function(event){ alert(event.data.msg); //event.data.msg is not available to the json callbac

我有一位同事问我为什么他不能从回调函数中访问事件参数。结果表明,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
    });    
});
试试这个:

$('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);
    });    
});
而不是
事件
。因为事件是全局对象
window.event
,当事件结束时它将变得未定义。您可以使用事件对象,而无需从参数中获取它,如下所示:

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

给定范围内存在的任何变量都可用于该范围内定义的所有函数。(这就是在JS中定义作用域的方式,如果您想了解其定义的细节,这可能是一个很好的切入点)


因为定义回调的函数表达式位于定义变量的函数内部,所以变量对它是可用的。

如果您不介意伪代码,请尝试将其视为嵌套块—这类事情

function foo()
{
  int bar=0;

  //inner block
  {
    bar++;
  }

}
或者更具体地说

function click()
{
 variable {msg: message}

  //inner block
  function(ev) 
  {
   ....     
  }
}

我回答了事件变量不可用的原因。确定。“但这不是问题所在。”克劳斯比斯科夫彼得森说,这正是一个问题。如果他使用
ev
而不是
event
,则
警报(ev.data.msg)
不会崩溃
然后我开始思考,为什么“message”甚至可以用于回调。有人能解释一下吗?
据我所知,他在问为什么变量
message
可用于回调函数。不是为什么事件被覆盖。@KlausByskovPedersen问这个问题是因为行为不同。如果
event
变量也可用,他不会问这个问题,你不同意吗?因为闭包。在这里阅读更多:+1对于Klaus(这是我用来理解它的链接)对于其他人来说,Klaus给出的链接对于理解闭包更好(参见对原始问题的评论)