13

通过 Closure Compiler 运行一个相当大的库时,我收到了很多"Unknown type"警告,当我的类型在自执行匿名函数中声明时,它们似乎发生了。这并没有什么特别之处,但是如果我去掉自执行函数,类型声明似乎可以工作(至少在这个简单的测试中)。

我不确定我的代码注释是否有问题,或者代码中是否有任何非法内容,但我认为这完全符合犹太教标准,也是模块化 API 的标准方法。

下面的测试代码创建了一个命名空间(只是一个普通的旧 JS 对象)并附加了一个枚举(一个对象字面量)和一个函数。

var mynamespace = {};
(function (mynamespace) {
    /**
     * Some enum.
     * @enum {number}
     */
    mynamespace.SomeEnum = {
        FOO: 1,
        BAR: 2
    };

    /**
     * Frazzle some type.
     * @param {mynamespace.SomeEnum} qux The type to frazzle.
     * @return {boolean} whether the operation succeeded.
     */
    mynamespace.frazzle = function(qux) {
        return true;
    }
}(mynamespace));

// call it
mynamespace.frazzle(mynamespace.SomeEnum.FOO);

看起来不错,对吧?闭包编译器错误:

[jscomp] Compiling 1 file(s) with 37 extern(s)
[jscomp] X:\dev\solclientjs\sdk\tools\jscomptest.js:14: WARNING - Parse error. Unknown type mynamespace.SomeEnum

[jscomp]      * @param {mynamespace.SomeEnum} qux The type to frazzle.
4

4 回答 4

3

编辑:

原来的答案是完全关闭。

这绝对似乎是编译器中的一个错误。我还没有找到关于这个确切问题的错误报告,但我发现了两个错误报告似乎解决了这个问题的反面(编译器应该发出警告,但除非你解开匿名函数,否则它不会)。

http://code.google.com/p/closure-compiler/issues/detail?id=134

http://code.google.com/p/closure-compiler/issues/detail?id=61

无论如何,当与类型表达式一起使用时,匿名函数看起来很不稳定。

于 2011-03-03T06:10:32.207 回答
3

在您的示例中,参数“mynamespace”被传递给全局mynamespace 对象的“别名”。为全局对象 (global mynamespace) 设置别名 (local mynamespace) 可防止对全局对象下的整个树进行优化。这对于高级模式下的 Closure Compiler 来说是个坏主意。

在局部变量下定义的任何函数都是易失的。编译器不知道(没有深入的代码流分析)本地“mynamespace”是全局“mynamespace”的别名。因此,它不会自动将您在局部变量下定义的任何内容与其别名的对象相关联。

正确的方法是:

选项#1,直接使用全局对象:

(function() {
    mynamespace.someEnum = ...
})();

选项 #2,使用 goog.scope 别名(假设您使用的是高级模式):

goog.scope(function() {
    var somevar = mynamespace;

    (function() {
        somevar.someEnum = ...
    })();
});

这两个选项都应该让你得到你想要的结果。但是,目前无法通过将参数放入包装闭包中来做您想做的事情。

于 2011-03-09T05:04:46.390 回答
1

闭包编译器在这里得到了改进。要更正上面的代码以使其被识别,您唯一需要做的就是将命名空间声明为@const:

/** @const */ var mynamespace = {};

然后识别类型。

于 2013-02-03T21:49:50.277 回答
0

闭包编译器不支持本地类型名称。名称必须是全局名称,并且在函数“mynamespace”中是本地名称。

于 2011-03-04T17:06:31.337 回答