[英]Why does google closure compiler warn about length of an array?
I have an object, with a property which is always an array or a null value like so: 我有一个对象,其属性始终是数组或空值,如下所示:
/** @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 closure compiler warns that property length is never defined on foo.optionalProperty, even though it's clearly an array if the line of code checking the length gets executed, and of course arrays have a length property. Google闭包编译器警告说,即使在执行检查长度的代码行中显然是数组,也永远不会在foo.optionalProperty上定义属性length,并且数组当然具有length属性。 Suggestions for eliminating/suppressing this warning? 有关消除/抑制此警告的建议?
UPDATE: OK, so I was kind of an idiot. 更新:好的,所以我有点白痴。 I tried to prepare a minimal example of the problem from my codebase, but this example actually does NOT throw a compiler warning, as Chad pointed out. 我试图从我的代码库中准备一个最小的问题示例,但是正如Chad指出的那样,该示例实际上不会引发编译器警告。 So I went digging, and found another place in my codebase where I had treated the property as an object rather than an array! 因此,我开始进行挖掘,并在代码库中找到了另一个将属性视为对象而非数组的地方! Here's a better code snippet to see the warning: 这是查看警告的更好的代码片段:
/** @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();
Thus, the warning that the 'length' property was not previously defined was legit. 因此,关于“长度”属性先前未定义的警告是合法的。 And I never would have had this confusion in the first place if I had typed this.optionalProperty as owler points out, because the compiler warns if you try to assign an array to something that's supposed to be an object. 而且,如果我输入owler指出的话,我绝对不会一开始就感到困惑,因为如果您尝试将数组分配给应该是对象的对象,编译器会发出警告。 I still maintain that the compiler could be smarter about type-checking inside a block like if(Array.isArray(something)) {} but the problem here was definitely user error. 我仍然认为,编译器在if(Array.isArray(something)){}之类的块中进行类型检查可能会更聪明,但是这里的问题肯定是用户错误。
You need to tell the compiler the type of the property, something like this 您需要告诉编译器属性的类型,像这样
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;
}
You could also use goog.isArray()
there. 您也可以在goog.isArray()
使用goog.isArray()
。 I don't know if the compiler will recognize Array.isArray
, it might. 我不知道编译器是否可以识别Array.isArray
。 But from the definition if it's not null then it is an array, and the compiler knows that. 但是根据定义,如果它不为null,则它是一个数组,并且编译器知道这一点。
The closure wiki has a good page called Annotating JavaScript for the Closure Compiler 闭包Wiki上有一个名为“ 为闭包编译器注释JavaScript”的好页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.