调试揭示模块模式:功能不在范围内直到被调用?

如果我在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不在?

Chrome开发工具的屏幕截图


迷人的问题。

privateFunction2所在范围publicFunction ,但publicFunction从来没有真正使用它。 我相信你在调试器中看到的是因为V8(Chrome的JavaScript引擎)出于各种原因(包括最小化内存使用)优化闭包的内容。

理论上,根据规范, publicFunction关闭(有一个持久的引用)所有定义范围内的符号。 具体而言,创建了一个执行上下文,用于调用最外层的匿名函数,并且该执行上下文具有包含关联绑定对象的词汇环境, publicFunction具有隐式匿名引用。 该绑定对象具有(在理论上)名称publicFunctionprivateFunction1privateFunction2和其他一些东西( arguments等)的属性。

但问题是, publicFunction实际上并没有引用除privateFunction1任何privateFunction1 ,并且代码已经存在,它不能引用任何其他内容。 为了引用其他任何东西,你必须改变它的代码,当然他们会做出不同的决定。 publicFunction的代码没有eval(string)new Function(string)调用,所以V8可以自由地对它所引用的符号进行静态分析。 这意味着,如果缺少调试器,则绑定对象保留其他属性没有任何意义。 他们从未使用过。

由于V8是一个积极优化的编译器(是,编译器),显然它从执行上下文的绑定对象中删除了死的属性。

如果我在publicFunction中添加一些使用privateFunction2的东西,我可以在控制台中引用它,就像我可以使用privateFunction1

链接地址: http://www.djcxy.com/p/69315.html

上一篇: Debugging Revealing Module Pattern: functions not in scope until called?

下一篇: Get actual dimensions of iOS view