Почему я не могу ссылаться на функцию, определенную с помощью объявления функции из отладчика? - PullRequest
1 голос
/ 10 февраля 2020

После разрыва оператора debugger при попытке вызвать foo throws ReferenceError . Кажется, что функция не определена в контексте или области действия сценария, как локальная переменная x.

example.js script:

/**
 * 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

Запуск процесса узла с прослушиванием инспектора :

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:

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

Я считаю, что возможность протестировать функцию с различными параметрами в течение одного сеанса отладки без перезапуска действительно полезна.

1 Ответ

1 голос
/ 28 февраля 2020

tldr: вам нужно иметь foo; где-то в той же области локальной функции.

Кажется, что когда вы находитесь в контексте отладки, вы на самом деле НЕ имеете доступа ко всем переменным из лексического scope, а точнее только для тех, которые уже появились в этой локальной области функций.

В качестве примера возьмем этот сценарий:

const a = 'something';

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

, при попытке вы получите ReferenceError доступ к a в отладочном репл.

Но если вы добавите a; где-нибудь в области действия функции, это сработает.

const a = 'something';

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

Причина, по которой это произошло с вами, заключается в том, что объявления функций поднимаются («перемещаются в начало файла», но на самом деле также выходят за пределы локальной области функций), тогда как выражения функций не поднимаются (таким образом, уже «появились» в функции). Вот почему это будет работать, когда вы измените function foo () { на const foo = function () {.

То же самое произойдет для var y; (все var переменные внутренне перемещены вверх - подняты), но будет работать для var y = 1;, поскольку оператор assign является своего рода «внешним видом».

Я не смог найти ничего об этом в Справочнике, но по собственному опыту отладчик работает так, по крайней мере, начиная с узла v6.

...