【问题标题】:Why does Firefox forget value of variable? Solution for debugging?为什么 Firefox 会忘记变量的值?调试解决方案?
【发布时间】:2014-06-05 20:24:26
【问题描述】:

步骤:

  1. 在 Firefox 29.0.1 (Windows 7 x64) 中打开页面:

    <!doctype html>
    <title>Test</title>
    <script>
        (function () {
            var x = 5, f = function () {
                setTimeout(f, 1000);
            };
            f();
        }());
    </script>
    
  2. 打开开发者工具 (F12)。

  3. 调试器中,设置断点:setTimeout(f, 1000);

  4. 一旦断点被​​命中,在控制台中评估x。结果:undefined

  5. 重新加载页面。断点在f 的第一次运行时命中。

  6. 评估x。结果:5

  7. 继续执行,当再次命中断点时,评估x。结果相同:5

我的假设:如果 Firefox 在第一次运行 f 时意识到不需要 x,那么它不会存储 x "with" f 的值.所以在随后对f 的调用中,x 的值是undefined。有趣的是,我在 Chrome 35 和 IE11 中看到了相同的行为。

问题: 发生了什么事?我可以配置 Firefox 以使 x 在第 4 步中评估为正确的值吗(见上文)?

【问题讨论】:

  • x 仅存在于您的函数中,并且您正尝试从外部访问它。
  • 我没有遇到这个问题。当我踏入它时,它的评估是正确的。 Fox 23.0.1 内置开发工具。如果您加载页面、启动调试器并尝试从那里进行调试,我会遇到调试器无法正常工作的情况。我以前必须加载页面、加载调试器、刷新页面才能使其工作。
  • @Meredith 我正在从setTimeout(f, 1000); 上的断点访问x,它位于函数的内部
  • @JoeSwindell 我实际上是在谈论内置的开发工具,而不是 Firebug。对不起,我把名字弄错了。无论如何,在打开开发工具的情况下重新加载页面并不能解决我的问题。要触发该问题,重要的是在加载页面时设置断点。
  • @feklee 如果没有断点,您将尝试从定义它的范围之外访问 x。 function() 包装器确保 x 未定义在页面的主范围内。如果您删除了外部函数包装器,则会定义 x。

标签: javascript firefox closures firefox-developer-tools


【解决方案1】:

看来你的假设是正确的。问题是当调试器未运行时,变量已被优化或删除。当您在调试器运行的情况下刷新页面时,它允许您访问函数的内部范围,以便您可以更轻松地调试代码。

如果那里没有断点,这是不可能的,所以必须禁用 JIT 编译器才能让你这样做。垃圾收集器还注意到这些仍然可以在范围内引用,因此不会删除这些变量。

如果 JIT 编译器正在运行,它会识别出 x 变量未在任何地方使用,并将其从生成的代码中删除。如果 JIT 编译器没有运行,垃圾收集 (GC) 将在 GC 循环运行时删除该变量,因为没有任何引用该变量的内容。

因为它无法撤消已经完成的操作,所以当你第一次下断点时它是未定义的。

即使您禁用 JIT 编译器,您也无法真正防止这种情况发生。虽然从技术上讲,您可以将垃圾收集限制设置得非常高以尝试阻止它这样做,甚至删除垃圾收集代码并重建 Firefox,但这是非常愚蠢的——您最终只会泄漏一堆内存,那就是比简单地刷新页面要麻烦得多。

有趣的是,如果您尝试做同样的事情,Firefox 31 (Aurora) 会提供更具描述性的错误消息:

Error: variable has been optimized out

【讨论】:

  • 感谢,特别是发现 Aurora 输出了更具描述性的错误消息!我刚刚在我的系统上确认了这一点。顺便说一句,您可能会删除答案的第一行:我现在也得到undefined。可能还有其他问题,或者当我复制错误消息时我在错误的选项卡中。
  • 很高兴知道这种行为的细节,它在 Firefox 中正确警告,但我想知道更严重的错误,如 bugzilla.mozilla.org/show_bug.cgi?id=977972bugzilla.mozilla.org/show_bug.cgi?id=582613 是否已在此版本中修复?老实说,我经常不得不尝试 Chrome/Chromium 的 JS 调试器,尽管 Firefox 的其他一切都更胜一筹。
  • @NoBugs:抱歉,我不太确定——我不太会使用 Aurora。
猜你喜欢
  • 2010-10-11
  • 2021-06-23
  • 1970-01-01
  • 2023-03-14
  • 2020-08-10
  • 2016-03-12
  • 2022-12-11
  • 2014-06-18
  • 1970-01-01
相关资源
最近更新 更多