使用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)。
您的示例中有几件事会导致问题:
- 代码示例中未定义
id
函数。编译器将假定它是一个外部函数。当设置VERBOSE
警告级别时,将针对这种情况发出警告或错误 - 您正在构造函数或原型方法之外使用
this
关键字。由于编译器可以将属性一直展平为全局变量,this
关键字引用的对象可能会发生变化 @this
注释告诉编译器函数中的this
关键字将是非空对象。我相信你用这个来消除编译器对前一点发出的警告。但是,现在您有责任在使用closure --compilation_level ADVANCED_OPTIMIZATIONS
0或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();
为了进一步了解这些问题,我建议阅读:
- 哪个汇编对我来说是正确的
- 了解闭包编译器施加的限制