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

Why does google closure compiler warn about length of an array?

本文关键字:数组 警告 谷歌 闭包 编译器 为什么      更新时间:2023-09-26

我有一个对象,它的属性总是一个数组或空值,像这样:

/** @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,即使它显然是一个数组如果检查长度的代码行被执行,当然数组有一个长度属性。消除/抑制此警告的建议?

更新:好吧,我是有点傻。我试图从我的代码库中准备一个最小的问题示例,但这个示例实际上并没有抛出编译器警告,正如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();

因此,先前没有定义'length'属性的警告是合法的。我一开始就不会有这种困惑如果我打了这个。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,它可能。但是根据定义,如果它不为空,那么它就是一个数组,编译器知道这一点。

闭包wiki有一个很好的页面叫做为闭包编译器注释JavaScript