【问题标题】:Scope and Asynchronous JavaScript范围和异步 JavaScript
【发布时间】:2010-08-02 22:58:54
【问题描述】:

我最近在工作中遇到了一个问题,至少根据我对 JavaScript 的了解,我得到了一个不可能的结果。我希望有人能解释这里发生了什么以及为什么实际结果与我的预期结果不同。

控制台中的预期结果

id: a , x: 1
id: b , x: 1
id: c , x: 1

控制台中的实际结果

id: c , x: 1
id: c , x: 2
id: c , x: 3

代码

function MyClass(id)
{
    var x = 0;

    return function()
    {
        return function()
        {
            x += 1;
            console.log("id: ", id, ", x: ", x);
        }
    }
}


function DoStuff(id)
{
    var q = MyClass(id);
    response_callback = q();
    setTimeout(function(){ response_callback(); }, 50);
}

DoStuff("a");
DoStuff("b");
DoStuff("c");

【问题讨论】:

  • setTimeout(function(){ response_callback(); }, 50); 可以替换为setTimeout(response_callback, 50)
  • @Dan,嗯,它可以,但是即使没有var,你也不会遇到狡猾的错误...
  • @Matthew:这听起来像是要获取狡猾的错误。 ;)
  • +1 个写得很好的问题,有趣地揭示了一个容易错过的错误。

标签: javascript asynchronous scope


【解决方案1】:
response_callback = q();

这个。您没有在任何范围内声明 response_callback,因此它隐含在全局范围内...

这意味着您每次调用 DoStuff() 时都会覆盖它。您认为您正在捕获和调用三个不同的函数,但只有一个......

 var response_callback = q(); // should set you back on track

当然,您现在的这种结构方式有点浪费MyClass 返回函数的能力。你实际上可以写:

function DoStuff(id)
{
  var q = MyClass(id);
  // ... do other strange and horrible things with q ...
  setTimeout(q(), 50);
}

...在没有不必要的关闭的情况下看到相同的结果。

【讨论】:

  • 谢谢你,总是简单的事情杀死你。错过这一点的唯一借口是关键时刻,这里的每个人都工作了一段时间,每天工作 12 小时,三双眼睛都没注意到。
猜你喜欢
  • 2012-10-04
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-03
  • 2015-03-11
相关资源
最近更新 更多