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

Google Closure calling undefined functions in advanced mode

本文关键字:调用 未定义 函数 模式 闭包 高级 Google      更新时间:2023-09-26

使用Google闭包编译器,我发现在某些情况下,它会调用未定义的本地函数。我发现的最简单的例子是:

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

哪个编译成

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

使用CCD_ 1编译时。默认编译(没有任何选项)编译为:

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

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

在我的研究过程中,我没有发现这种行为的任何原因,老实说,我对此感到非常困惑。这是一个收尾错误还是我做出了某种错误的假设?

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

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

  1. 代码示例中未定义id函数。编译器将假定它是一个外部函数。当设置VERBOSE警告级别时,将针对这种情况发出警告或错误
  2. 您正在构造函数或原型方法之外使用this关键字。由于编译器可以将属性一直展平为全局变量,this关键字引用的对象可能会发生变化
  3. @this注释告诉编译器函数中的this关键字将是非空对象。我相信你用这个来消除编译器对前一点发出的警告。但是,现在您有责任在使用closure --compilation_level ADVANCED_OPTIMIZATIONS0或apply调用函数时显式设置this对象。此外,属性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();

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

  • 哪个汇编对我来说是正确的
  • 了解闭包编译器施加的限制