コード構造の章で学んだように、コメントには、//
で始まる1行コメントと、/* ... */
の複数行コメントがあります。
通常、コメントはコードの動作方法や理由を説明するために使用します。
一見すると、コメントは明白なように思えるかもしれませんが、プログラミング初心者はしばしば誤った使い方をします。
悪いコメント
初心者は、コード内で「何が起こっているか」を説明するためにコメントを使用する傾向があります。例えば、こんな感じです。
// This code will do this thing (...) and that thing (...)
// ...and who knows what else...
very;
complex;
code;
しかし、優れたコードでは、このような「説明的な」コメントの量は最小限に抑えられるべきです。真面目な話、コードはコメントなしでも理解しやすいはずです。
これについて素晴らしいルールがあります。「コードが不明確でコメントが必要な場合は、代わりにコードを書き直すべきかもしれない」
レシピ:関数をファクタリングする
場合によっては、コードの一部を関数に置き換えることが有益です。例えば、以下の例のように。
function showPrimes(n) {
nextPrime:
for (let i = 2; i < n; i++) {
// check if i is a prime number
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert(i);
}
}
ファクタリングされた関数 isPrime
を使用したより良い例。
function showPrimes(n) {
for (let i = 2; i < n; i++) {
if (!isPrime(i)) continue;
alert(i);
}
}
function isPrime(n) {
for (let i = 2; i < n; i++) {
if (n % i == 0) return false;
}
return true;
}
これで、コードを簡単に理解できるようになりました。関数自体がコメントになります。このようなコードは *自己記述的* と呼ばれます。
レシピ:関数を作成する
また、このような長い「コードシート」がある場合
// here we add whiskey
for(let i = 0; i < 10; i++) {
let drop = getWhiskey();
smell(drop);
add(drop, glass);
}
// here we add juice
for(let t = 0; t < 3; t++) {
let tomato = getTomato();
examine(tomato);
let juice = press(tomato);
add(juice, glass);
}
// ...
以下のように、関数にリファクタリングするのがより良い方法かもしれません。
addWhiskey(glass);
addJuice(glass);
function addWhiskey(container) {
for(let i = 0; i < 10; i++) {
let drop = getWhiskey();
//...
}
}
function addJuice(container) {
for(let t = 0; t < 3; t++) {
let tomato = getTomato();
//...
}
}
繰り返しになりますが、関数自体が何が起こっているかを伝えます。コメントするものは何もありません。また、コード構造も分割された方が優れています。各関数が何を行い、何を受け取り、何を返すかが明確になります。
実際には、「説明的な」コメントを完全に避けることはできません。複雑なアルゴリズムもあります。また、最適化を目的とした賢い「調整」もあります。しかし、一般的には、コードをシンプルで自己記述的に保つように努めるべきです。
良いコメント
説明的なコメントは通常良くないということです。では、どのようなコメントが良いのでしょうか?
- アーキテクチャを記述する
- コンポーネントの概要、それらがどのように相互作用するか、さまざまな状況での制御フローなど、コードの鳥瞰図を提供します。コードを説明する高レベルのアーキテクチャ図を作成するための特別な言語である UML があります。間違いなく学習する価値があります。
- 関数のパラメータと使用法をドキュメント化する
- 関数の使用法、パラメータ、戻り値をドキュメント化するための特別な構文である JSDoc があります。
例えば、
/**
* Returns x raised to the n-th power.
*
* @param {number} x The number to raise.
* @param {number} n The power, must be a natural number.
* @return {number} x raised to the n-th power.
*/
function pow(x, n) {
...
}
このようなコメントを使用すると、関数のコードを見なくても、関数の目的を理解し、正しく使用することができます。
ところで、WebStorm のような多くのエディターもそれらを理解でき、オートコンプリートや自動コードチェックを提供するために使用できます。
また、JSDoc 3 のようなツールがあり、コメントから HTML ドキュメントを生成できます。JSDoc の詳細については、https://jsdoc.dokyumento.jp を参照してください。
- なぜタスクはこのように解決されるのか?
-
記述されている内容は重要です。しかし、何が起こっているかを理解するためには、記述されていないことがさらに重要になる場合があります。なぜタスクはまさにこの方法で解決されるのでしょうか?コードは答えを与えません。
タスクを解決する方法が多数ある場合、なぜこの方法なのでしょうか?特に、それが最も明白な方法ではない場合はなおさらです。
このようなコメントがないと、次のような状況が発生する可能性があります。
- あなた(または同僚)がしばらく前に書かれたコードを開くと、それが「最適ではない」ことに気が付きます。
- 「当時の私はどれだけ愚かだったのだろう、今はどれだけ賢くなったのだろう」と思い、より「明白で正しい」方法で書き直します。
- …書き換えたいという衝動は良かったのですが、その過程で「より明白な」解決策が実際には欠けていることに気づきます。なぜそうなのかをうっすらと覚えていますが、それは以前に試したことがあるからです。正しいバリアントに戻しますが、時間は無駄になりました。
解決策を説明するコメントは非常に重要です。それらは、正しい方法で開発を継続するのに役立ちます。
- コードの微妙な機能はありますか?それらはどこで使用されていますか?
-
コードに何か微妙で直感的でないものがある場合は、必ずコメントする価値があります。
まとめ
優れた開発者の重要な兆候は、コメントの存在、そしてコメントがないことです。
優れたコメントは、コードを適切に保守し、時間を置いてから戻ってきて、より効果的に使用できるようにします。
以下にコメントする
- 全体的なアーキテクチャ、高レベルのビュー。
- 関数の使い方。
- 重要なソリューション、特にすぐに明らかではない場合。
以下のコメントは避ける
- 「コードがどのように動作するか」と「コードが何をするか」を伝えるもの。
- コードがシンプルで自己記述的であるため、それらを必要としないようにすることが不可能な場合にのみ、コメントを挿入してください。
コメントは、JSDoc3のような自動ドキュメント化ツールにも使用されます。それらはコメントを読み取り、HTMLドキュメント(または別の形式のドキュメント)を生成します。
コメント
<code>
タグを使用し、数行の場合は<pre>
タグで囲み、10行以上はサンドボックス (plnkr、jsbin、codepen…) を使用してください。