【问题标题】:Why can I not reference a function defined using function declaration from a debugger?为什么我不能从调试器引用使用函数声明定义的函数?
【发布时间】:2020-05-25 06:41:39
【问题描述】:

debugger 语句中断后,尝试调用foo 会抛出ReferenceError。该函数似乎没有在脚本的上下文或范围中定义,例如本地 x 变量。

example.js脚本:

/**
 * Source code example
 */

const x = 'x'
let y

function foo(param = 'foo') {
  console.log(param)
}

// const f = foo // foo throws error if commented out and referenced from debugger

debugger

用inspector监听启动节点进程:

node --inspect-brk example.js

内置 Node.js 调试器:

$ node inspect 127.0.0.1:9229
Break on start in scripts/example.js:5
  3  */
  4 
> 5 const x = 'x'
  6 let y
  7 
debug> c
break in scripts/example.js:14
 12 // const f = foo // foo throws error if commented out and referenced from debugger
 13 
>14 debugger
 15 
debug> exec foo()
ReferenceError: foo is not defined
    at eval (eval at <anonymous> (/path/to/scripts/example.js:14:1), <anonymous>:1:1)
    at Object.<anonymous> (/path/to/scripts/example.js:14:1)
    at Module._compile (internal/modules/cjs/loader.js:952:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11

在 VS Code 的调试控制台中:

foo()
ReferenceError: foo is not defined

在 Chrome DevTools 的控制台中:

foo()
VM88:1 Uncaught ReferenceError: foo is not defined
    at eval (eval at <anonymous> (/path/to/scripts/example.js:14:1), <anonymous>:1:1)
    at Object.<anonymous> (/path/to/scripts/example.js:14:1)
    at Module._compile (internal/modules/cjs/loader.js:952:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11

我发现能够在一个调试会话中测试具有不同参数的函数而无需重新启动真的很有用。

【问题讨论】:

  • v10.16.3为例,可以引用该函数。在v13.11.0,仍然没有。

标签: javascript node.js debugging node-inspector


【解决方案1】:

tldr:您需要在同一本地函数范围内的某处拥有foo;

似乎当您在调试上下文中时,实际上您无法访问词法范围内的所有变量,而只能访问已经出现在此本地函数范围内的变量。

以这个脚本为例:

const a = 'something';

(() => {
    debugger;
})()

当您尝试在调试副本中访问 a 时,这将产生一个 ReferenceError

但如果你在函数范围内的某处添加a;,它就会起作用。

const a = 'something';

(() => {
    a;
    debugger;
})()

发生这种情况的原因是因为函数声明被提升(“移动到文件顶部”,但实际上也在本地函数范围之外),而函数表达式没有被提升(因此已经“出现”在功能)。这就是为什么当您将function foo () { 更改为const foo = function () { 时它会起作用的原因。

var y; 也会发生同样的事情(所有var 变量都在内部向上移动 - 已提升)但对于 var y = 1; 将有效,因为分配操作是一种“外观”。

我在参考中找不到任何关于此的内容,但根据我自己的经验,调试器至少从 node v6 开始就是这样工作的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    相关资源
    最近更新 更多