javascript – 调试显示模块模式:函数在调用之前不在范围内?

如果我在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有一个隐式的匿名引用.该绑定对象具有(在理论上)名称为publicFunction,privateFunction2和其他一些东西(参数等)的属性.

但问题是publicFunction实际上并没有引用除privateFunction1之外的任何东西,并且对于它的代码,它不能引用任何其他东西.为了引用其他任何东西,你必须改变它的代码,当然它们V8会做出不同的决定. publicFunction中的代码没有eval(字符串)或新的Function(字符串)调用,因此V8可以自由地对它引用的符号进行静态分析.这意味着,没有调试器,绑定对象保留那些其他属性没有任何意义.他们从未使用过.

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

如果我向使用privateFunction2的publicFunction添加一些内容,那么我可以从控制台中引用它,就像我可以使用privateFunction1一样.

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...