jan*_*oeh 7 javascript closures scope google-chrome-devtools
如果我在Chrome开发者工具中运行此代码:
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
};
})();
Run Code Online (Sandbox Code Playgroud)
为什么privateFunction1在断点范围内,而privateFunction2不是?

有趣的问题。
privateFunction2 属于的范围publicFunction,但publicFunction从未实际使用过它。我相信您在调试器中看到的内容是因为 V8(Chrome 的 JavaScript 引擎)出于各种原因(包括最小化内存使用)优化了闭包的内容。
理论上,根据规范,publicFunction封闭(具有持久引用)其定义范围内的所有符号。具体来说,为调用最外层的匿名函数创建了一个执行上下文,并且该执行上下文具有一个词法环境,该环境具有关联的绑定对象,该对象publicFunction具有隐式的匿名引用。该绑定对象具有(理论上)名称publicFunction、privateFunction1、privateFunction2和一些其他内容(arguments等等)的属性。
但问题是,publicFunction除了 之外,它实际上没有引用任何东西privateFunction1,而且有了它的代码,它就不能引用其他任何东西。为了让它引用其他任何东西,你必须更改它的代码,当然 V8 会做出不同的决定。中的代码publicFunction没有eval(string)ornew Function(string)调用,因此 V8 可以自由地对其引用的符号进行静态分析。这意味着,如果没有调试器,绑定对象就没有必要保留这些其他属性。它们从未被使用过。
由于 V8 是一个积极优化的编译器(是的,编译器),显然它从执行上下文的绑定对象中删除了死属性。
如果我添加一些可以publicFunction用于privateFunction2任何用途的东西,我就可以像我一样从控制台引用它privateFunction1。