为什么函数内的变量对于在该函数内声明的回调函数可见?

Why are variables inside functions visible to callback functions declared inside that function?

本文关键字:函数 回调 声明 变量 为什么      更新时间:2023-09-26

我有一个同事问我为什么他不能从回调函数中访问事件参数。原来,jquery似乎在调用结束后将事件设置为null,并创建一个临时的局部变量来解决这个问题(见下文)。

然后这让我思考,为什么'message'甚至可用于回调。有人能解释一下吗?

$('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
    });    
});

存在于给定作用域中的任何变量都可用于在该作用域中定义的所有函数。(这就是JS中作用域是如何定义的,如果你想了解作用域是如何定义的,语言规范的这一部分可能是一个很好的切入点)

由于定义回调的函数表达式在定义变量的函数中,因此它可以使用该变量

试试这个:

$('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);   
});

如果您原谅这些伪代码——试着把它们想象成嵌套块——这类东西

function foo()
{
  int bar=0;
  //inner block
  {
    bar++;
  }
}

或更具体地说

function click()
{
 variable {msg: message}
  //inner block
  function(ev) 
  {
   ....     
  }
}