Closure编译器将闭包内的定义视为重定义

时间:2011-09-21 14:50:59

标签: javascript google-closure-compiler google-closure

我一直在使用谷歌关闭,试图让大量的JavaScript进行干净利用,以便使用谷歌编译器进行最小化。我遇到了一个问题:

goog.provide('test');
goog.provide('test2');

/**
 * @constructor
 */
test = function () {
    this.x = 10;
    this.y = 13;
};

(function () {
    /**
     * @constructor
     */
    test2 = function () {
        this.x = 10;
        this.y = 13;
    };
})();

前者很好。后者生成一个常量重定义错误:

JSC_CONSTANT_REASSIGNED_VALUE_ERROR. constant test2 assigned a value more than once at /home/hbrown/tmp/closure-test/foo.js line 16 : 10
BUILD FAILED: 1 error(s), 0 warning(s)

有没有办法强制plovr / closure编译器允许这个构造?我环顾四周,一无所获。


后来:还有一点,为什么关闭/ plovr会将test2视为常量?我怀疑它与plovr / closure在调用goog.provide时为test2创建命名空间有关。很高兴看到它在生成错误时正在使用的中间形式。

3 个答案:

答案 0 :(得分:0)

我正在输入这个作为答案,即使这只是一个猜测,因为评论对代码来说很糟糕。

你有没有试过这样的事情:

test2 = (function () {
    /**
     * @constructor
     */
    function inner_test2() {
        this.x = 10;
        this.y = 13;
    };

    // ...

    return inner_test2;
})();

我不认为这是一个方便的重构,特别是如果匿名函数是大而复杂的,但是看看它是什么让编译器感到困惑会很有趣(等等)。

答案 1 :(得分:0)

根据您需要匿名函数的原因,您可以尝试使用goog.scope替换匿名函数

http://closure-library.googlecode.com/svn/docs/closure_goog_base.js.html

答案 2 :(得分:0)

在函数闭包之外声明测试2,而不指定它:

var test2;

(function() {
    test2 = function(...

我意识到这不是你想要的Closure Compiler配置更改,但它既可以提高代码的可读性,又可以解决Closure Compiler的异议。

Closure Compiler的一些内容实际上是谷歌内部的Javascript代码指南,因为它的历史。因此,例如,您不能使用with语句,因为这是针对策略的,即使您作为公共用户只想缩小代码,并且可能有一个允许在您公司使用with语句的策略。

那就是说,我认为在函数闭包中声明全局不是最好的做法(即使它是合法的Javascript)。编写一个寻找/(\w[\w\d-]+) = function/并在有问题的文件顶部用var声明它的脚本并不难。并且,它可能会导致所有修改过的文件更容易被新的编码器分析给它。

您剩下的选择是修改开源Closure Compiler代码,以便发出警告,而不是有关此违反Google JS政策的错误。