不求谌解

不求谌解

💻 Web Dev / Creative 💗 ⚽ 🎧 🏓
twitter
github
jike
email

変数の命名の芸術

image

これは最近翻訳した記事1(私の 2 番目の翻訳記事です👏)。一部の箇所で少し変更を加え、元の記事にもいくつかの内容を追加しました。誤解を招かないように願っています。楽しんでください!

コンピュータ科学の世界では、2 つの難しいことしかないと言われています。キャッシュの無効化(cache invalidation)と名前の付け方(naming things)。- Phil Karlton

名前の付け方については、時には非常に困難なことがあります。しかし、それに取り組む価値があります。以前、次のようなコードを見たことがありますか?

const convertObj = (x, y, z) => {
    const k = Object.keys(x);
    return k.map((key) => {
        return {
            [y]: key,
            [z]: x[key],
        }
    });
}

これが何をしているのかすぐにわかりますか?もちろん、このコードを行ごとに読み終えると、何を表しているのか理解できるかもしれません。しかし、変数の命名方法がもっと優れている場合、このコンテンツを理解するのはもっと簡単になるでしょう。

良い変数の命名は非常に重要です、特に動的型言語では、変数の正確な意味を理解するために事前に定義された変数の基本型を使用することはできません。しかし、動的型言語で良い命名方法を使用できれば、静的型言語に比べてコードが読みやすくなります。

次に、変数の命名方法に関するいくつかの基本的なルールを共有します。これらは私の経験に基づくものです。さまざまな基本型の変数を比較することで、いくつかの例を挙げます。まずは配列から始めましょう。

配列#

配列オブジェクトは順序付けられたデータの集まりであり、各項目の基本型はほぼ同じです。配列は複数の変数値を含むため、変数の命名は意味のある複数形であるべきです。

// 悪い例
const fruit = ['りんご', 'バナナ', 'キュウリ'];
// まあまあの例
const fruitArr = ['りんご', 'バナナ', 'キュウリ'];
// 良い例
const fruits = ['りんご', 'バナナ', 'キュウリ'];
// とても良い例 - "names"は配列の内容が文字列であることを示唆しています
const fruitNames = ['りんご', 'バナナ', 'キュウリ'];
// エレガントな例
const fruits = [{
    name: 'りんご',
    genus: 'マルス'
}, {
    name: 'バナナ',
    genus: 'ムサ'
}, {
    name: 'キュウリ',
    genus: 'キュウキュウス'
}];

ブール値#

ブール型はtrueまたはfalseの 2 つの値しか持ちません。変数の命名には、変数のタイプを読者に理解させるために、『is』、『has』、または『can』を接頭辞として使用すると良いでしょう。

// 悪い例
const open = true;
const write = true;
const fruit = true;

// 良い例
const isOpen = true;
const canWrite = true;
const hasFruit = true;

述語関数(boolean 値を返す関数)に遭遇した場合、名前付き関数の後に変数を命名することは少し面倒です。

const user = {
  fruits: ['りんご']
}
const hasFruit = (user, fruitName) => {
  user.fruits.includes(fruitName)
}
// このboolean変数をどのように命名すればよいでしょうか?
const x = hasFruit(user, 'りんご');

関数名にhasの接頭辞を付けたので、hasProjectPermissionのような形式で x という boolean 変数を命名することはできません。この場合、hasFruit関数にcheckまたはgetを追加して述語(has)を修飾することができます。

const checkHasFruit = (user, fruitName) => {
  user.fruits.includes(fruitName)
}
const hasFruit = checkHasFruit(user, 'りんご');

数値#

数値型については、数値を説明する単語を考えてみましょう。例えば、maximumminimumtotalなどです。

// 悪い例
const pugs = 3;
// 良い例
const minPugs = 1;
const maxPugs = 5;
const totalPugs = 3;

関数#

関数は動詞と名詞の組み合わせで命名するべきです。関数がオブジェクトのプロトタイプ上で特定の動作を行う場合、その名前はそれを反映するようにする必要があります。actionResourceは命名の形式として参考になります。例えば、getUserです。

// 悪い例
userData(userId);
userDataFunc(userId);
totalOfItems(items);
// 良い例
getUser(userId);
calculateTotal(items);

通常、変数の値を変換する関数の名前の接頭辞としてtoを使用します。

// 私はこれが好きです
toDollors('euros', 20);
toUppercase('a string')

子アイテムを反復処理する場合、このような命名方法をよく使用します。関数内で 1 つの引数を受け取る場合、配列名の単数形を使用するべきです。

// 悪い例
const newFruits = fruits.map(x => {
  doSomething(x);
});
// 良い例
const newFruits = fruits.map(fruit => {
  doSomething(fruit)
})

最初に戻る#

最初のコードをリファクタリングしてみましょう

const arrayToObject = (array, id, name) => {
  const arrayList = Object.keys(array);
  return arrayList.map((key) => {
      return {
          [id]: key,
          [name]: array[key]
      }
  });
}

自己省察#

// 以前の命名 => rsshubプロジェクト
// 1. 記事リストを取得する
const list = $('.con_list li h3')
      .find('a')
      .map((i, e) => $(e).attr('href'))
      .get();
// 2. 取得した記事のURLにリクエストを送信する
const res = await got.get(itemUrl);

// 改善された命名
const articleLists = $('.con_list li h3')
      .find('a')
      .map((i, list) => $(list).attr('href'))
      .get();

const responseData = await got.get(itemUrl);

Footnotes#

  1. オリジナルの記事へのリンク

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。