微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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一样.

原文地址:https://www.jb51.cc/js/157737.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐