2022年5月22日

コメント

コード構造の章で学んだように、コメントには、// で始まる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 を参照してください。

なぜタスクはこのように解決されるのか?

記述されている内容は重要です。しかし、何が起こっているかを理解するためには、記述されていないことがさらに重要になる場合があります。なぜタスクはまさにこの方法で解決されるのでしょうか?コードは答えを与えません。

タスクを解決する方法が多数ある場合、なぜこの方法なのでしょうか?特に、それが最も明白な方法ではない場合はなおさらです。

このようなコメントがないと、次のような状況が発生する可能性があります。

  1. あなた(または同僚)がしばらく前に書かれたコードを開くと、それが「最適ではない」ことに気が付きます。
  2. 「当時の私はどれだけ愚かだったのだろう、今はどれだけ賢くなったのだろう」と思い、より「明白で正しい」方法で書き直します。
  3. …書き換えたいという衝動は良かったのですが、その過程で「より明白な」解決策が実際には欠けていることに気づきます。なぜそうなのかをうっすらと覚えていますが、それは以前に試したことがあるからです。正しいバリアントに戻しますが、時間は無駄になりました。

解決策を説明するコメントは非常に重要です。それらは、正しい方法で開発を継続するのに役立ちます。

コードの微妙な機能はありますか?それらはどこで使用されていますか?

コードに何か微妙で直感的でないものがある場合は、必ずコメントする価値があります。

まとめ

優れた開発者の重要な兆候は、コメントの存在、そしてコメントがないことです。

優れたコメントは、コードを適切に保守し、時間を置いてから戻ってきて、より効果的に使用できるようにします。

以下にコメントする

  • 全体的なアーキテクチャ、高レベルのビュー。
  • 関数の使い方。
  • 重要なソリューション、特にすぐに明らかではない場合。

以下のコメントは避ける

  • 「コードがどのように動作するか」と「コードが何をするか」を伝えるもの。
  • コードがシンプルで自己記述的であるため、それらを必要としないようにすることが不可能な場合にのみ、コメントを挿入してください。

コメントは、JSDoc3のような自動ドキュメント化ツールにも使用されます。それらはコメントを読み取り、HTMLドキュメント(または別の形式のドキュメント)を生成します。

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善する点について提案がある場合は、コメントする代わりに GitHub issue を送信 するか、pull request を送信してください。
  • 記事の中で何か理解できない場合は、詳しく説明してください。
  • 数語のコードを挿入するには、<code> タグを使用し、数行の場合は <pre> タグで囲み、10行以上はサンドボックス (plnkrjsbincodepen…) を使用してください。