愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

JsDocにやさしいJSの書き方

最近、比較的真面目にJsDocを書くという機会があったので。

(※この記事の前提はJsDoc 3.2.2です)

JSで適当に名前空間的なものを切ってコードを書いていくと、

/**
 * @class
/*
function Klass() {
}

Klass.prototype.foo = function () {
};

my.name.space.Klass = Klass;

みたいな書き方がいいか、

/**
 * @class
/*
my.name.space.Klass = function() {
};

my.name.space.Klass.prototype.foo = function() {
};

みたいな書き方がいいか、という割とどうでも良い選択(意味的には同じなので)を迫られることがありますが、これは結論的には後者の方がよくて、

  • 後者だとJsDocが勝手にKlassがmy.name.spaceに属することを判断してdocumentを作ってくれるが、前者の場合は@memberofとか使わないとその辺を理解してくれない
  • 前者だと余計なシンボルがスコープに定義される (Klass)

という二点において、後者を選んだ方がよいです。

ちなみに僕は「メソッド宣言とかを短く書けるから」という理由で前者を選んでいましたが、JsDocを書く段になって後悔しました。

この辺の話は今後JsDocそのものが賢くなると改善されるかもしれませんし、browserifyなどのモダンなモジュールシステム(?)を使っている場合はあまりこういう話題は登場しないかもしれませんね。

JsDocのannotationを真面目に書くのって割と面倒なので、出来るだけannotationなしでJsDocに構造を理解してもらえるようにコード書いたほうが後々ラクですよ、というお話でした。

Googleは内部的には違うものを使っていると思いますが、JsDocの書き方自体はclosure libraryが参考になる気がしています。

google/closure-library · GitHub

色々なライブラリが群雄割拠している昨今のJS業界ですが、closure libraryにはGoogleの伝統と知恵が詰まってると思うんだ。多分。