JSDoc使い方メモ

JSDoc で API ドキュメントを生成する方法と、一部のドキュメンテーションタグの使い方についてメモする。

#環境
##OS
Windows7 64bit

##Java
1.7.0_51

##JSDoc
3.2.2

#インストール
##Java
Mozilla Rhino を使った方法でドキュメントを生成するので、 Java が必要。
インストール方法は割愛。

##JSDoc 3
[GitHub](https://github.com/jsdoc3/jsdoc) からダウンロードできる。

tags から v3.2.2 を選択して、 zip でダウンロードする。

zip を解凍したら、解凍後のフォルダにパスを通し、コマンドラインからヘルプを表示できることを確認する。

```bat:
>jsdoc --help
OPTIONS:
        -t, --template <value>          The path to the template to use. Default: path/to/jsdoc/templates/default
        -c, --configure <value>         The path to the configuration file. Default: path/to/jsdoc/conf.json
        -e, --encoding <value>          Assume this encoding when reading all 
（以下略）
```

#ドキュメントを生成する
```text:フォルダ構成
src
└─main
    └─java
        └─webapp
            └─js
                    test.js
```

```js:test.js
/**
 * @classdesc This is MyClass.
 * @constructor
 */
function MyClass() {
    /**
     * method
     * @param hoge {Object} - hoge Object
     */
    this.method = function() {
    };
}
```

コマンドプロンプトでトップのフォルダに移動し、以下のコマンドを実行する。

```bat:
>jsdoc -r src
```

すると、 `out` フォルダの下に API ドキュメントが HTML 形式で出力される。

```bat:
>cd out

>tree /f
│  global.html
│  index.html
│  MyClass.html
│  test.js.html
│
├─scripts
│  │  linenumber.js
│  │
│  └─prettify
│          Apache-License-2.0.txt
│          lang-css.js
│          prettify.js
│
└─styles
        jsdoc-default.css
        prettify-jsdoc.css
        prettify-tomorrow.css
```

ブラウザで開くと↓のような感じ。

![jsdoc_sample.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/108b5b06-b784-167c-c87d-0d563a9e87ea.jpeg)


#ドキュメンテーションタグの書き方
##namepath について
`@link` タグなどでクラスのインスタンスメンバーやインナーメンバーを参照するときは、 `namepath` という記法を使う。

```js:
/**
 * <ul>
 *   <li>{@link Hoge#instanceMethod}
 *   <li>{@link Hoge~innerFunction}
 *   <li>{@link Hoge.staticMethod}
 * </ul>
 * @constructor
 */
function Hoge() {
    /**
     * インスタンスメソッド
     */
    this.instanceMethod = function() {};
    
    /**
     * インナー関数
     */
    function innerFunction() {}
}

/**
 * スタティックメソッド
 */
Hoge.staticMethod = function() {};
```

![jsdoc_namepath.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/0e08dbe7-3c23-b3ab-bb76-0c49abe6fc57.jpeg)

|記法|指すモノ|
|:--|:--|
|ClassName#memberName|インスタンスメンバー|
|ClassName~memberName|インナーメンバー|
|ClassName.memberName|スタティックメンバー|

##@param : 関数の引数を宣言する
###基本形
```js:
/**
 * 関数
 * @param {string} str - 文字列の引数
 * @param {number} num - 数値の引数
 * @param {Object} obj - オブジェクトの引数
 * @param {MyClass} myClass - MyClass インスタンスの引数
 */
function func() {}

/**
 * @constructor
 */
function MyClass() {}
```

![jsdoc_param_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/f58a586e-b891-487a-604e-0da77276044c.jpeg)

###引数が任意であることを宣言する
```js:
/**
 * 関数
 * @param {string} [str] - 文字列の引数
 * @param {number} [num=300] - 数値の引数
 */
function func() {}
```

![jsdoc_param_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/14a70e90-3bf4-9966-ca2a-b1f0cd77832b.jpeg)

省略したときのデフォルト値も宣言できる。

##@return : 戻り値を説明する
```js:
/**
 * 関数
 * @return {boolean} 真偽値を返す
 */
function func() {}
```

![jsdoc_return.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/572892f7-e912-4c56-395b-4efb654900b6.jpeg)


##@throws : 関数がスローする例外について説明する
```js:
/**
 * 関数
 * @throws {string} エラーメッセージをスローする
 */
function func() {}
```

![jsdoc_throws.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/4b391f15-5805-6325-3586-c4ce9cea867d.jpeg)


##@constructor : 関数をコンストラクタ関数として宣言する
```js:
/**
 * ここの説明はコンストラクタの説明になる。
 * @constructor
 */
function MyClass() {}
```

![jsdoc_class.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/befd0c2b-9b87-4f37-d722-543141fb5c40.jpeg)

##@classdesc : クラスの説明を記述する
```js:
/**
 * コンストラクタの説明
 * @constructor
 * @classdesc クラスの説明
 * @param {string} param - パラメータ
 */
function MyClass(param) {
}
```

![jsdoc_classdesc.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/bff6233e-4e84-cea1-44d6-c44a05ed7866.jpeg)

##@extends : 親クラスを宣言する
```js:
/**
 * 親クラス
 * @constructor
 */
function ParentClass() {
}

/**
 * 子クラス
 * @constructor
 * @extends ParentClass
 */
function ChildClass() {
}

ChildClass.prototype = new ParentClass();
```

![jsdoc_augments.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/cdd9a435-fe4e-2081-e721-6af34690be59.jpeg)

`@augments` タグでも同じように親クラスを明示できる。

##@link : リンクを貼る
```js:
/**
 * <ul>
 *   <li>{@link http://www.google.co.jp Google}
 *   <li>{@link MyClass#hoge}
 * </ul>
 * @constructor
 */
function MyClass() {
    
    /**
     * hoge 関数
     * {@link MyClass}
     */
    this.hoge = function() {};
}
```

![jsdoc_link.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/bf12f9de-683e-6793-b31c-4383d007901e.jpeg)

##@example : 実装例を提示する
```js:
/**
 * 関数
 * @example
 * var result = plus(1, 3);
 * // result = 4
 */
function plus(a, b) {
    return a + b;
}
```

![jsdoc_example.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/172b0d9e-b769-3422-3287-69c2ec156b90.jpeg)

##@deprecated : 非推奨を宣言する
```js:
/**
 * 関数
 * @deprecated 使ってはいけない
 */
function func() {}
```

![jsdoc_deprecated.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/d2be9c28-29db-9aca-6879-c5dfb5883bcb.jpeg)

##@type : 変数の型を明示的に宣言する
```js:
/**
 * これはオブジェクトです。
 * @type {object}
 */
var hoge = {};

/**
 * これは数値です。
 * @type {number}
 */
var fuga = 10;

/**
 * これは {@link MyClass} のインスタンスです。
 * @type {MyClass}
 */
var piyo = new MyClass();

/**
 * @constructor
 */
function MyClass() {}
```

![jsdoc_tyoe.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/84e50c7d-a174-3404-c4ef-eb5ffcd59735.jpeg)

##@typedef : 独自の型を宣言する
```js:
/**
 * Hoge 型です。
 * @typedef {object} Hoge
 */
```

![jsdoc_tyoedef.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/c966f26f-21c4-a9d9-fb9d-f98b718da856.jpeg)

##@prop : プロパティを宣言する
```js:
/**
 * Hoge 型です。
 * @typedef {object} Hoge
 * @prop {string} str - 文字列のプロパティ
 * @prop {number} num - 数値のプロパティ
 */
```

![jsdoc_prop.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/0d0d84de-89b1-6498-8c6c-d4d027e91d89.jpeg)


##@file : ファイルの説明を記述する
```js:hoge.js
/**
 * @file ほげファイル
 */
```

```js:fuga.js
/**
 * @file ふがファイル
 */
```

![jsdoc_file.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/f355c87c-48a6-5c3a-5b92-f6d1b8d07521.jpeg)

##@callback : コールバック関数の定義を宣言する
```js:
/**
 * @constructor
 */
function MyClass() {
    /**
     * メソッド
     * @param {MyClass~MyCallback} callback - コールバック関数
     */
    this.execute = function(callback) {
    };
}

/**
 * コールバック関数の説明
 * @callback MyClass~MyCallback
 * @param {number} hoge - 引数１
 * @param {string} fuga - 引数２
 */
```

![jsdoc_callback.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/7289e8d1-b5db-56d6-4726-cae49b3a3c41.jpeg)

ドキュメントコメントだけ書いて、 `@callback` タグをつけると、コールバック関数単独で型を定義できる。
上記例ではタグのパラメータに `MyClass~MyCallback` と指定しているので、 `MyClass` の内部メンバーとして型が定義されている。

他のクラスなどでも使用するようなコールバック関数の場合は以下のようにしてグローバルに宣言することもできる。

```js:
/**
 * @constructor
 */
function MyClass() {
    /**
     * メソッド
     * @param {MyCallback} callback - コールバック関数
     */
    this.execute = function(callback) {
    };
}

/**
 * コールバック関数の説明
 * @callback MyCallback
 * @param {number} hoge - 引数１
 * @param {string} fuga - 引数２
 */
```

![jsdoc_callback_global.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/db63bd15-c2c1-0a40-8e72-bde0c2b63c7e.jpeg)

##@event : イベントオブジェクトを宣言する
```js:
/**@constructor*/
function MyClass() {
    
    /**
     * イベントをキックする関数
     * @fires MyClass~MyEvent
     */
    this.kickEvent = function() {};
    
    /**
     * イベント実行キック時に渡されるオブジェクト
     * @event MyClass~MyEvent
     * @type {object}
     * @property {string} name - イベント名
     */
}
```

![jsdoc_event.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/4c2770b5-ea5a-f794-c19d-64ffce1fdfd8.jpeg)

`@fire` タグで、実行するイベントを宣言できる。

##@namespace : 名前空間を宣言する
###基本
```js:
/**
 * @namespace
 */
var aaa = {
    /**
     * @constructor
     */
    Hoge: function() {},
    
    /**
     * @namespace
     */
    bbb: {
        /**
         * @constructor
         */
        Fuga: function() {}
    }
};

/**
 * @namespace
 */
aaa.bbb.ccc = {
    /**
     * @constructor
     */
    Piyo: function() {}
};
```

![jsdoc_namespace_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/69f36dce-249e-5e6d-5886-18b6c98f44c9.jpeg)

![jsdoc_namespace_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/8ffeee27-434d-6182-f273-d85eaeb08b1d.jpeg)

![jsdoc_namespace_3.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/34e86328-c98c-1374-39b5-947564d9dbe5.jpeg)

###名前空間のオブジェクトを一旦別の変数に代入している場合
```js:
/**
 * @namespace
 */
var aaa = {};

var alias = aaa;

/**
 * @namespace
 */
alias.bbb = {};
```

![jsdoc_namespace_4.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/c7a20906-b634-3db2-1c36-7d3ca1ba04ad.jpeg)

![jsdoc_namespace_5.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/d989f281-9211-ce09-4cff-35eb676a47c5.jpeg)

そのままだと `bbb` は単独の名前空間として認識されてしまう。

`aaa.bbb` というふうにしたい場合は以下のようにする。

```js:
/**
 * @namespace
 */
var aaa = {};

var alias = aaa;

/**
 * @namespace bbb
 * @memberof aaa
 */
alias.bbb = {};
```

![jsdoc_namespace_6.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/efe7c16e-57fe-d194-b97b-740c15d9b595.jpeg)

![jsdoc_namespace_7.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/0af5cace-5dd6-fef7-e204-cb2b3d1ffcd9.jpeg)

`@namespace` で名前を明示して、 `@memberof` で所属している名前空間を明示する
（２階層以上ある場合は `@memberof aaa.bbb` のように `.` 区切りで所属する名前空間の完全名を指定する）。


#参考
- [jsdoc3/jsdoc · GitHub](https://github.com/jsdoc3/jsdoc)
- [JsDoc Toolkitを使う！](http://www12.atwiki.jp/aias-jsdoctoolkit/)
- [JSDoc Toolkit→JSDoc 3移行ガイド - Technology of DeNA](http://engineer.dena.jp/2013/05/migration-from-jsdoc2-to-jsdoc3.html)