How can I "recursively" stringify a javascript function which calls other scoped functions?

The only good way to do this is to start from a parent scope that encloses all functions foo eventually references. For example, with your foo and bar, if you want to pass foo into another context such that bar is callable as well, pass a function that declares both foo and bar, and returns foo. For example:

const makeFoo = () => {
  let bar = () => { alert(1) }
  let foo = () => { bar() }
  return foo;
};
const makeFooStr = makeFoo.toString();

// ...

const makeFooFunc = new Function(' return (' + makeFooStr + ').apply(null, arguments)');
const foo = makeFooFunc();
foo();

Implementing this sort of thing well does require premeditated design like above (unfortunately). You can't really include all ancestor LexicalEnvironments (the internal map of variable names to values in a given scope) when stringifying.