为什么 google 闭包编译器会警告数组的长度?
Why does google closure compiler warn about length of an array?
我有一个对象,它带有一个 属性,它始终是一个数组或空值,如下所示:
/** @constructor */
function MyObject() {
// optionalProperty always contains an array or null
this.optionalProperty = null;
}
MyObject.prototype.initialize = function() {
this.optionalProperty = [1,2,3];
};
var foo = new MyObject();
foo.initialize();
if(Array.isArray(foo.optionalProperty)) {
var length = foo.optionalProperty.length;
}
Google 闭包编译器警告说 属性 长度从未在 foo.optionalProperty 上定义,即使它显然是一个数组,如果检查长度的代码行被执行,当然数组的长度为 属性。关于 eliminating/suppressing 这个警告的建议?
更新:
好的,所以我有点像个白痴。我试图从我的代码库中准备一个最小的问题示例,但这个示例实际上并没有抛出编译器警告,正如查德指出的那样。所以我继续挖掘,在我的代码库中找到了另一个地方,在那里我将 属性 视为一个对象而不是一个数组!这是一个更好的代码片段来查看警告:
/** @constructor */
function MyObject() {
// optionalProperty always contains an array or null
this.optionalProperty = null;
}
MyObject.prototype.initialize = function() {
this.optionalProperty = {};
this.optionalProperty.a = 1;
};
MyObject.prototype.otherMethod = function() {
if(Array.isArray(this.optionalProperty)) {
for (var i = 0; i < this.optionalProperty.length; i++) {
console.log(i);
}
}
};
var foo = new MyObject();
foo.initialize();
foo.otherMethod();
因此,之前未定义 'length' 属性 的警告是合法的。如果我像 owler 指出的那样输入 this.optionalProperty ,那么我一开始就不会产生这种混淆,因为如果您尝试将数组分配给应该是对象的东西,编译器会发出警告。我仍然认为编译器可以更智能地在块内进行类型检查,例如
如果(Array.isArray(某事)){}
但这里的问题肯定是用户错误。
你需要告诉编译器 属性 的类型,像这样
function MyObject() {
/** optionalProperty always contains an array or null
* @type {?Array}
*/
this.optionalProperty = null;
}
MyObject.prototype.initialize = function() {
this.optionalProperty = [1,2,3];
}
foo = new MyObject();
foo.initialize();
if (this.optionalProperty != null) {
var length = foo.optionalProperty.length;
}
您也可以在那里使用 goog.isArray()
。我不知道编译器是否会识别 Array.isArray
,它可能会。但是根据定义,如果它不是 null 那么它就是一个数组,编译器知道这一点。
closure wiki 有一个很好的页面叫做 Annotating JavaScript for the Closure Compiler
我有一个对象,它带有一个 属性,它始终是一个数组或空值,如下所示:
/** @constructor */
function MyObject() {
// optionalProperty always contains an array or null
this.optionalProperty = null;
}
MyObject.prototype.initialize = function() {
this.optionalProperty = [1,2,3];
};
var foo = new MyObject();
foo.initialize();
if(Array.isArray(foo.optionalProperty)) {
var length = foo.optionalProperty.length;
}
Google 闭包编译器警告说 属性 长度从未在 foo.optionalProperty 上定义,即使它显然是一个数组,如果检查长度的代码行被执行,当然数组的长度为 属性。关于 eliminating/suppressing 这个警告的建议?
更新: 好的,所以我有点像个白痴。我试图从我的代码库中准备一个最小的问题示例,但这个示例实际上并没有抛出编译器警告,正如查德指出的那样。所以我继续挖掘,在我的代码库中找到了另一个地方,在那里我将 属性 视为一个对象而不是一个数组!这是一个更好的代码片段来查看警告:
/** @constructor */
function MyObject() {
// optionalProperty always contains an array or null
this.optionalProperty = null;
}
MyObject.prototype.initialize = function() {
this.optionalProperty = {};
this.optionalProperty.a = 1;
};
MyObject.prototype.otherMethod = function() {
if(Array.isArray(this.optionalProperty)) {
for (var i = 0; i < this.optionalProperty.length; i++) {
console.log(i);
}
}
};
var foo = new MyObject();
foo.initialize();
foo.otherMethod();
因此,之前未定义 'length' 属性 的警告是合法的。如果我像 owler 指出的那样输入 this.optionalProperty ,那么我一开始就不会产生这种混淆,因为如果您尝试将数组分配给应该是对象的东西,编译器会发出警告。我仍然认为编译器可以更智能地在块内进行类型检查,例如 如果(Array.isArray(某事)){} 但这里的问题肯定是用户错误。
你需要告诉编译器 属性 的类型,像这样
function MyObject() {
/** optionalProperty always contains an array or null
* @type {?Array}
*/
this.optionalProperty = null;
}
MyObject.prototype.initialize = function() {
this.optionalProperty = [1,2,3];
}
foo = new MyObject();
foo.initialize();
if (this.optionalProperty != null) {
var length = foo.optionalProperty.length;
}
您也可以在那里使用 goog.isArray()
。我不知道编译器是否会识别 Array.isArray
,它可能会。但是根据定义,如果它不是 null 那么它就是一个数组,编译器知道这一点。
closure wiki 有一个很好的页面叫做 Annotating JavaScript for the Closure Compiler