【问题标题】:can you turn off javascript garbage collector for a debugging mode?你可以关闭 javascript 垃圾收集器的调试模式吗?
【发布时间】:2017-10-18 14:54:47
【问题描述】:

当我调试 javascript 时,我经常遇到由于范围问题而无法访问应该通过闭包提供给我的变量的情况。

对于这种情况,我可以向上遍历堆栈级别以将自己置于正确的范围内,但这很令人困惑,并且在您处理承诺/异步调用时不起作用。

我相信这是垃圾收集器标记和清除未使用变量的功能(如果我错了,请纠正我)。

是否有一种模式可以用来保存闭包变量(是的,我意识到这不会导致垃圾收集,但在调试时仍然有用,并且不应该影响应用程序的行为)

有这个问题的代码:

function hello(arr, foo, bar) { 
  arr.forEach(item => {
    debugger; // HERE `foo`, `arr` and `bar` are reference errors in debugger evaluation
  }); 
  return 1 
} 
hello([1,2,3], 'foo', 'bar')

------------编辑-------------

更新示例

【问题讨论】:

  • not able to access abc even though I am suppose to 对我来说就像一个魅力。您能否提供一个示例来重现您的实际问题? I can traverse up a stack level to put myself in the correct scope for this case, but this is quite confusing and doesn't do the trick when you deal with promises / async calls 所以你在理解嵌套作用域时遇到了问题,以及函数如何从周围作用域访问变量?还是您所拥有的时间有问题,并且变量可能已经改变了它们的值,直到承诺得到解决?
  • 您可以尝试关闭 jit 编译,即让它在解释器模式下运行
  • @the8472 是这个名字吗?
  • @Thomas 并不是说​​我没有时间上下遍历,而是在调试时不能在运行时访问特定点的当前变量。遍历只能解决同步代码模式,所以就是这样,但这困扰我的主要原因是调试器没有反映真正的可访问范围。
  • 实际上,您说 “我可以遍历堆栈级别以将自己置于这种情况下的正确范围内,但这很令人困惑,并且在您处理承诺/异步调用。” - 这实际上是关于堆栈行走不显示变量还是关于垃圾收集?

标签: javascript debugging garbage-collection closures mark-and-sweep


【解决方案1】:

假设这实际上是由于优化决策而没有首先捕获外部范围 - 这意味着不涉及垃圾收集 - 您可以尝试以下方法:

let singularity = null;
function blackhole(val) {
  singularity = val;
}

function someScope() {
  var abc = 'abc'
  var arr = [1...100] // pseudocode

  arr.map(n => {
      debugger;
      blackhole(abc); // forces abc to be captured
      // or ...
      eval(""); // eval leads to more conservative optimizations
    })
}

function someScope() {
  var abc = 'abc'
  var arr = [1...100] // pseudocode

  // normal functions are not as easily optimized as arrow functions
  arr.map(function() {
    debugger;
  })
}

或者,假设您使用的是 firefox,请转到 about:config 并设置 javascript.options.baselinejit = false

一般的想法是强制编译器不执行丢弃未使用的外部范围的优化。

【讨论】:

  • 我很确定您不需要singularity,只需提及变量abc 作为无操作的参数就足够了。但最好是安全而不是抱歉:-)
  • 好吧,在 java 和 C 语言中,优化器会直接看穿它并将其作为死代码消除。随着 JS 优化器变得更好,它们也可能变得更好。最好在那个区域小心。
  • 这实际上是我试图避免的,当调试可能不容易重新运行的代码时,我希望控制台能够反映变量的正确引用,而不必添加对它的引用并重新启动过程。
猜你喜欢
  • 1970-01-01
  • 2012-12-28
  • 2019-03-02
  • 2016-11-18
  • 2013-08-10
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多