2016-09-25 57 views
0

我有一個對象,用這始終是一個數組或像這樣空值的屬性:爲什麼谷歌封閉編譯器警告數組的長度?

/** @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; 
} 

谷歌關閉編譯器警告說,物業長度決不會在foo.optionalProperty定義,即使它是明確的數組如果檢查長度的代碼行被執行,當然數組有長度屬性。消除/抑制此警告的建議?

更新: 好的,所以我是一個白癡。我試圖從我的代碼庫中準備一個最小的問題例子,但是這個例子實際上並沒有拋出編譯器警告,正如Chad指出的那樣。所以我開始挖掘,並在我的代碼庫中找到另一個地方,我將該屬性視爲對象而不是數組!這裏有一個更好的代碼片段來看到警告:

因此,「長度」屬性之前沒有定義的警告是合法的。如果我輸入this.optionalProperty作爲owler指出,因爲編譯器會警告,如果您嘗試將數組分配給某個應該是某個對象的對象,那麼我就不會有這種困惑。我仍然認爲,如果(Array.isArray(something)){} 這樣的塊在 之類的塊內進行類型檢查,編譯器會更聰明,但這裏的問題肯定是用戶錯誤。

+0

一個良好的網頁?新版本正確識別'foo.optionalProperty'的類型 - 上面的測試代碼在沒有任何警告的情況下爲我工作(有一些修改)。將'/ ** @constructor * /'添加到'function MyObject'和一個'var'來正確定義'foo'。 –

+0

我使用的是7月14日的編譯器;但我剛剛更新到9月14日版本,仍然收到警告。我將更正上面的示例代碼,很好地捕獲缺少的jsdoc和變量聲明。 – RobP

回答

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,那麼它就是一個數組,編譯器知道這一點。

封閉wiki有您使用的是舊版本的編譯器叫做Annotating JavaScript for the Closure Compiler

+1

這是一個錯過的機會 - 在由Array.isArray檢查保護的if語句中,編譯器可以收緊這些類型。 –

+0

@ChadKillingsworth我的觀點正是如此。 – RobP

+0

請參閱上面的我的更新 - 此答案實際上並不解釋編譯器警告的原因,因爲這是由於代碼不在原始文章中導致的。然而,如這裏所示鍵入變量是一個非常好的做法,並且會標記上述啞代碼,所以我會接受/ upvote這個答案。 – RobP