2

使用 Google Closure Compiler 我发现在某些情况下它会调用未定义的本地函数。我发现的显示这一点的最小示例是:

var apa = {
    /** @this {!Object} */
    foo: function () { this.bar(id()); },
    bar: function (x) { return [x]; }
};

apa.foo();

编译为

(function(){this.a(id())})();

编译时使用closure --compilation_level ADVANCED_OPTIMIZATIONS. 默认编译(没有任何选项)编译为:

var apa={foo:function(){this.bar(id())},bar:function(a){return[a]}};apa.foo();

在最小版本this.a中是未定义的。

在我的研究中,我没有发现任何导致这种行为的任何迹象,老实说,我对此感到非常困惑。这是关闭中的错误还是我做出了某种错误的假设?

(任何关于如何解决这个问题的建议都将不胜感激,因为我非常需要在不手动操作的情况下尽可能地减少 js)。

4

1 回答 1

3

您的示例有几件事会导致问题:

  1. id函数未在代码示例中定义。编译器将假定它是一个外部函数。设置VERBOSE警告级别时,将针对这种情况发出警告或错误。
  2. 您在this构造函数或原型方法之外使用关键字。由于编译器可以将您的属性一直展平为全局变量,因此this关键字引用的对象可能会发生变化。
  3. @this注释告诉编译器函数中的关键字this将是一个非空对象。我确定您使用它来消除编译器发出的关于前一点的警告。但是,现在您有责任在this使用call或调用函数时显式设置对象apply。此外,属性bar没有在类型上定义Object,因此编译器会更加混乱。

以下是您的示例的更正版本:

function id() {
  // this definition was created as an illustration and to prevent the 
  // example from being removed as dead code.
  var id_ = math.random();
  window.console.log(id);
  return id_;
}

var apa = {
  foo: function () {
    apa.bar(id());
    // id could also be called externally as follows:
    // apa.bar(window['id']());
  },
  bar: function (x) { return [x]; }
};

apa.foo();

为了进一步了解这些问题,我建议阅读:

于 2013-09-03T13:19:53.507 回答