我正在使用一个使用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压缩它们。
答案 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;
会解决问题但我不知道这是否是最好的解决方案。
我真的不知道编译器是如何工作的,但我可以想象如果你有一个构造函数,它需要将实例属性分配给构造函数内的this
或MyClass.prototype
。
如果删除@constructor
注释并省略new
,则没有警告(但编译的代码仅为console.log("Hello World");
。