Google Closure在高级模式下调用未定义的函数

时间:2013-09-02 15:35:20

标签: javascript google-closure-compiler

使用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而不用手工操作。)

1 个答案:

答案 0 :(得分:3)

您的示例有几处导致问题:

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

    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();
    

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