使用以下代码:
function baz() {
var x = "foo";
function bar() {
debugger;
};
bar();
}
baz();
我得到了这个意外的结果:
当我更改代码时:
function baz() {
var x = "foo";
function bar() {
x;
debugger;
};
bar();
}
我得到了期望的结果:
而且,如果内部函数中有任何对 eval
的调用,我可以按照自己的意愿访问我的变量(无论我传递什么给 eval
)。
与此同时,Firefox 开发工具在这两种情况下都给出了期望的行为。
Chrome 的调试器比 Firefox 不那么方便是怎么回事?我观察到这种行为已经有一段时间了,包括版本号为 41.0.2272.43 beta (64 位)的 Chrome 浏览器。
是不是 Chrome 的 JavaScript 引擎会在可能的情况下“展开”函数?
有趣的是,如果我添加第二个变量,并且内部函数确实引用了它,那么 x
变量仍然是未定义的。
我知道,在使用交互式调试器时,作用域和变量定义通常会有些怪异之处,但根据语言规范,似乎应该有一个“最佳”的解决方案来处理这些怪异之处。因此,我非常好奇这是否是因为 Chrome 进行了比 Firefox 更深层次的优化。而且这些优化在开发期间是否可以轻松禁用(也许当开发工具打开时它们应该被禁用?)。
此外,我可以使用断点和 debugger
语句重现这个问题。
debugger;
这一行并没有从bar
函数内部调用。因此,在调试器中暂停时查看堆栈跟踪:堆栈跟踪中是否提到了bar
函数?如果我是正确的,那么堆栈跟踪应该显示它在第5行、第7行、第9行暂停。 - David Knipetemp1
附加到控制台上,您可以使用它来访问作用域条目。 - Pablobar
使用,因此在bar
的执行上下文中,它对调试器不可见,因为运行时没有义务在该上下文中保留/使不必要的事物可见。 - Lawrence Dol