2012-06-24 91 views
2

我正在使用使用return语句来公开类方法的设计模式。Google Closure编译器,如何优雅地处理JSC_INEXISTENT_PROPERTY?

问题是:我得到一个很多JSC_INEXISTENT_PROPERTY警告在关闭编译器的高级模式,这使得它很难检查实际问题的警告。该图案的

实施例I使用:

// ==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"); 

哪个是奇怪的,因为封闭理解的代码是什么正确编写代码,将myPublicFunc重命名为a。那么为什么我得到这个警告?难道我做错了什么?

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

回答

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

添加

MyClass.prototype.myPublicFunc = null; 

就解决了问题,但我不知道这是否是最好的解决方案。我不知道编译器是如何工作的,但我可以想象如果你有一个构造函数,它期望实例属性被分配到构造函数内的thisMyClass.prototype

如果删除@constructor注释并忽略new,那么就没有警告(但编译后的代码仅是console.log("Hello World");

3

您还可以使用:

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

该功能可与“新”的叫,但不会返回“MyClass的”的一个实例。

+0

当我测试它时,将新注释与记录类型一起使用会生成“错误类型注释”错误。 –

+0

这是不幸的,我们应该修复它。 – John

+1

它使用typedef。 –

相关问题