ここではカタいクラス=フェイルファストで、コンパイル時に問題を発見しやすく、かつ保守しやすいクラス と定義する。
基本的には goog.ui.Component あたりを読むと勉強になる。もちろんネームスペースでユーティリティメソッド群を実装する場合にも通じる。
goog.asserts.assert を使う
「ここではこういう理由からこういう状態であるべき」をコードで明記できる。例えばgoog.ui.Componentでは以下のようにして使っている。
goog.ui.Component.prototype.getRequiredElementByClass = function(className) {
var el = this.getElementByClass(className);
goog.asserts.assert(el, 'Expected element in component with class: %s',
className);
return el;
};
@param, @type, @return で ! や ? をきちんと書く
Javaの人としてはundefinedやnullになりえる場合は明記したい。
JSDocで@param {?Object} object description
とすればnullになる可能性がある(nullを許容する)ことの明記になる。undefinedは{(Object|undefined)}
とする。
逆に、nullになる可能性がない(nullを許容しない)場合は@param {!Object} object description
で良い。
@paramの場合は=
を使って省略可能であることも明記できる。この場合、=の右側にデフォルト値を併記しておくとドキュメント生成に良い。
追記:はてぶコメントで指摘いただきました、stringはプリミティブなのでnullにはならないそうです。
@override の代わりに @inheritDoc を使えないか検討する
ドキュメントで説明すべき事柄がスーパークラスと同じ場合、@override の代わりに @inheritDoc を使うことでスーパークラスのドキュメントを使える。
Closure Library自身にもけっこうドキュメントが空っぽなメソッドがあるが、このタグを使えば解決できることが多い。
追記:はてぶコメントで指摘いただきました、deprecatedになっているそうです。
@typedef とRecord TypeでPlain Objectの中身について型情報を明記する
Record Typeを使うと、Plain Objectの中身(プロパティ)について名前と型情報を明記できる。Plain Objectを使いたい、値を表すクラスを作るまでもないケースで有用。
同じPlain Objectを使うメソッドが複数ある場合、JSDocをコピペするのではなく、@typedefで型を定義すると良い。例えば goog/fs/fs.js には2メソッドを持つPlain ObjectがUrlObject_として定義されている。
goog.fs.UrlObject_;
XxxLike を理解して使う
JavaScriptでよくある「ArrayみたいだけどArrayじゃないモノで、だけどArrayとして使える」オブジェクトをXxxLike と表すのがClosure Library流っぽい。Array等を扱うメソッドで代わりにこれらを使うようにすると、カタさを保ちつつ柔軟性を上げられる。
- goog.array.ArrayLike
- goog.date.DateLike
- goog.events.EventLike
- goog.net.XhrLike
ちなみに goog.dom.isNodeLike() というメソッドもあるが型として定義されているわけではない。
ツールをちゃんと使う
省略。別途資料等を参照。