2

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

问题是:我在 Closure Compiler 的高级模式下收到很多警告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 压缩这些。

4

3 回答 3

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');

Another annotation option is to create an interface and type-cast the returned object to be that interface. This option would be useful when multiple functions return an object that conforms to the same interface.

于 2012-06-25T14:16:44.740 回答
3

You can also use:

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

The function can be called with "new" but doesn't return an instance of "MyClass".

于 2012-06-25T15:51:41.317 回答
1

添加

MyClass.prototype.myPublicFunc = null;

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

我真的不知道编译器是如何工作的,但我可以想象,如果你有一个构造函数,它期望实例属性被分配给构造函数this内部或MyClass.prototype.

如果您删除@constructor注释并省略new,则不会出现警告(但编译后的代码只有console.log("Hello World");.

于 2012-06-24T15:21:55.007 回答