为什么谷歌闭包编译器会警告数组的长度?

时间:2016-09-25 00:32:40

标签: javascript arrays google-closure-compiler

我有一个对象,其属性始终是数组或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)){} 但这里的问题肯定是用户错误。

1 个答案:

答案 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,那么它就是一个数组,编译器就知道了。

闭包维基有一个名为Annotating JavaScript for the Closure Compiler

的好页面