Debugging a module's expanding template: functions are not displayed in the scope before the call?

If I ran this code in Chrome Developer Tools:

var test = (function () { var publicFunction, privateFunction1, privateFunction2; privateFunction1 = function privateFunction1() { return true; }; privateFunction2 = function privateFunction2() { return true; }; publicFunction = function publicFunction() { privateFunction1(); debugger; }; return { publicFunction: publicFunction }; })(); 

why is privateFunction1 in scope at the breakpoint, but privateFunction2 is not?

Screenshot of Chrome Dev Tools

+7
source share
1 answer

A fascinating question.

privateFunction2 is in the scope of publicFunction , but publicFunction never uses it. I believe that what you see in the debugger is due to the fact that V8 (the Chrome JavaScript engine) optimizes the contents of closures for various reasons (including minimizing memory usage).

In theory, according to the specification, publicFunction closes (has a permalink) all the characters in the area where it is defined. In particular, an execution context was created to call your external anonymous function, and in the execution context, a lexical environment with an associated object with which publicFunction has an implicit, anonymous reference. This binding object has properties on it (in theory), the names publicFunction , privateFunction1 , privateFunction2 and some other things ( arguments , etc.).

But the fact is that publicFunction actually doesn’t refer to anything except privateFunction1 , and with the code for it, it cannot refer to anything else. In order to refer to anything else, you will have to change your code, and, of course, V8 will make a different decision. The code in publicFunction has no calls to eval(string) or new Function(string) , so V8 can perform static analysis on the characters it refers to. This means that if there is no debugger, it makes no sense for the binding object to retain these other properties. They are never used.

Since V8 is an aggressively optimizing compiler (yes, the compiler), it seems to remove dead properties from the execution context binding object.

If I add something to a publicFunction that uses privateFunction2 for something, I can refer to it from the console, as I can privateFunction1 .

+4
source

All Articles