Google Closure Compiler,如何优雅地处理JSC_INEXISTENT_PROPERTY?

时间:2012-06-24 15:15:11

标签: javascript google-closure-compiler

我正在使用一个使用return语句来公开公共类方法的设计模式。

问题是:我在Closure Compiler的高级模式下收到{strong>很多的JSC_INEXISTENT_PROPERTY警告,这使得检查实际上重要的警告变得很困难。

我使用的模式示例:

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==

/**
 * @constructor
 */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
}

var myClassInstance = new MyClass();
myClassInstance.myPublicFunc('Hello World');

警告:

JSC_INEXISTENT_PROPERTY: Property myPublicFunc never defined on MyClass \
    at line 16 character 0
myClassInstance.myPublicFunc('Hello World');

输出(格式化):

(new function() {
    return {
        a: function(a) {
            console.log(a)
        }
    }
}).a("Hello World");

这很奇怪,因为Closure了解代码正在做什么并正确编译代码,将myPublicFunc一致地重命名为a。那为什么我会收到这个警告?我做错了吗?

注意:我不想关闭这些警告,因为它也会隐藏我真正关心的警告。我也不想使用带引号的字符串或导出,因为我确实希望Closure压缩它们。

3 个答案:

答案 0 :(得分:4)

您的功能注释不正确。它实际上不是构造函数,在这种情况下,new关键字是不必要的。您的函数只返回一个具有myPublicFunc属性的匿名类型。

要注释这样的模式,您可以使用记录类型:

/** @return {{myPublicFunc: function(string) }} */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
};

var myClassInstance = MyClass(); // new keyword not needed
myClassInstance.myPublicFunc('Hello World');

另一个注释选项是创建一个接口并将返回的对象类型转换为该接口。当多个函数返回符合相同接口的对象时,此选项很有用。

答案 1 :(得分:3)

您也可以使用:

/** @type {function(new:{myPublicFunc: function(string)} )} */
var MyClass = function() {...

可以使用“new”调用该函数,但不返回“MyClass”的实例。

答案 2 :(得分:1)

添加

MyClass.prototype.myPublicFunc = null;

会解决问题但我不知道这是否是最好的解决方案。

我真的不知道编译器是如何工作的,但我可以想象如果你有一个构造函数,它需要将实例属性分配给构造函数内的thisMyClass.prototype

如果删除@constructor注释并省略new,则没有警告(但编译的代码仅为console.log("Hello World");