哪一個要用?
這在某種程度上是個人喜好和編碼風格的問題。 Closure Compiler更傾向於使用類,接口,方法等在Java中找到的僞古典繼承模式,這與其他方法不同。見Michael Bolin的Inheritance Patterns in JavaScript。
另請參閱Annotating JavaScript for the Closure Compiler它具有最簡潔的各種標籤的定義。
對於我自己,我使用僞古典繼承模式。因此,99%的時間我正在使用@constructor
來定義類,這些類與new
關鍵字一起使用。這些類也被標記爲@struct
,因此它們具有固定的一組屬性和方法。大約80%的我的課程聲明他們@implement
和@interface
,因爲這允許我使用接口類型,而不是綁定到特定的類實現。
偶爾我會用@typedef
來定義一個對象,它有一些最小的屬性集合。對我來說,這種類型的對象通常沒有定義它的函數,它只是聚合一些屬性的一種方式。
下面是我的代碼示例:
/** A regular expression and the replacement string expression to be used in a
* `String.replace()` command.
* @typedef {{regex: !RegExp, replace: string}}
* @private
*/
Terminal.regexPair;
我可以使用的typedef別處:
/** Set of regular expressions to apply to each command.
* @type {!Array.<!Terminal.regexPair>}
* @private
*/
this.regexs_ = [];
的優點是,它很容易使這種類型的東西:
/** Add regular expression and replacement string to be used by `String.replace()`
* for transforming script commands before they are executed.
* @param {!RegExp} regex regular expression for finding a name to transform
* @param {string} replace the replacement string for use with `String.replace()`
*/
Terminal.prototype.addRegex = function(regex, replace) {
this.regexs_.push({regex:regex, replace:replace});
};
請注意,我使用{regex:regex, replace:replace}
創建了一個匿名對象,而不是使用new
運營商。然而,編譯器正在檢查此對象是否具有由Terminal.regexPair
定義的必需(最小)屬性集。
但是還有很多關於如何編寫JavaScript代碼的其他哲學。你當然可以定義一個需要具有指定簽名的函數的typedef。
我認爲一個很好的答案應該涵蓋typedef,record和interface之間的區別。 –