我有一个对象,其属性始终是数组或null值,如下所示:
/** @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永远不会定义属性长度,即使它检查长度的代码行被执行时它显然是一个数组,当然数组也有一个length属性。消除/抑制此警告的建议?
更新: 好的,所以我有点白痴。我试图从我的代码库中准备一个问题的最小例子,但是这个例子实际上并没有抛出编译器警告,正如Chad指出的那样。所以我去挖掘,并在我的代码库中找到另一个地方,我将该属性视为对象而不是数组!这是一个更好的代码片段,可以看到警告:
/** @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();
因此,警告说&#39;长度&#39;之前没有定义的财产是合法的。如果我在owler指出的情况下输入this.optionalProperty,我就不会有这种混乱,因为如果你试图将一个数组分配给一个应该是一个对象的东西,编译器会发出警告。我仍然认为编译器可以更聪明地在块内部进行类型检查
if(Array.isArray(something)){}
但这里的问题肯定是用户错误。
答案 0 :(得分:2)
您需要告诉编译器属性的类型,类似这样
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,那么它就是一个数组,编译器就知道了。