如果我在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
};
})();
为什么
privateFunction1
在范围内位于断点,而privateFunction2
不在范围内? 最佳答案
有趣的问题。privateFunction2
在publicFunction
的范围内为,但publicFunction
从未实际使用它。我相信您在调试器中看到的是因为V8(Chrome的JavaScript引擎)出于各种原因(包括最小化内存使用)而优化了闭包的内容。
从理论上讲,根据规范,publicFunction
在定义它的范围内关闭(具有持久引用)。具体来说,为调用最外面的匿名函数创建了一个execution context,并且该执行上下文具有一个lexical environment和一个关联的binding object,该publicFunction
具有隐式的匿名引用。该绑定(bind)对象具有(在理论上)名称为publicFunction
,privateFunction1
,privateFunction2
和其他一些属性(arguments
等)的属性。
但是问题是publicFunction
实际上除了privateFunction1
之外什么都没有引用,并且有了相应的代码,它不能引用其他任何东西。为了引用其他内容,您必须更改其代码,当然V8会做出不同的决定。 publicFunction
中的代码没有eval(string)
或new Function(string)
调用,因此V8可以自由对其引用的符号进行静态分析。这意味着,在没有调试器的情况下,保持对象的其他属性毫无意义。他们从未使用过。
由于V8是一个积极优化的编译器(是的,是编译器),显然,它从执行上下文的绑定(bind)对象中删除了无效属性。
如果我在使用publicFunction
进行任何操作的privateFunction2
中添加了某些内容,则可以从控制台引用它,就像我可以使用privateFunction1
一样。