JavaScript の変数名の付け方:camelCase を基本にした命名規則ガイド

JavaScript では、変数、関数、パラメーター、オブジェクトのプロパティには camelCase(cartTotal、fetchOrders)、クラスと React コンポーネントには PascalCase(ShoppingCart)を使い、CONSTANT_CASE はプログラムの実行中ずっと固定の値(MAX_RETRIES)だけに取っておきます。Google と Airbnb の JavaScript スタイルガイドは、ここまでは一致しており、JavaScript 自身の組み込みもこのパターンに従っています。
この記事では、まずエンジンが実際に強制することを取り上げ、次にその上に重なる慣習、最後にチームの意見が分かれる細かな場面を扱います。どの const の値を大文字にするか、private フィールド、略語、API から届く snake_case のデータです。
JavaScript 自体が許すもの
言語のルールは短いものです。識別子は、文字、アンダースコア、ドル記号のいずれかで始まり、2 文字目以降には数字も使えます。文字は ASCII に限りません。MDN 自身の例は、ドイツ語の単語 Früh です。名前は大文字・小文字が区別されるので、total と Total は別の変数であり、new、class、delete のような予約語は変数名に使えません。
let total = 1;
let Total = 2; // a different variable
const café = "ok"; // Unicode letters are allowed
const $price = 9.99;
const _unused = null;
// const 2fast = true; // SyntaxError: can't start with a digit
// const new = 1; // SyntaxError: reserved wordプロパティ名はさらに緩く、引用符で囲めばどんな文字列でも使えます。headers["Content-Type"] が書けるのはそのためです。これらのルールを超える部分はすべて慣習であり、だからこそ、取り決めておく価値があります。
変数、関数、プロパティには camelCase
JavaScript で名前を付けるもののほとんどは、camelCase が基本です。値には名詞、関数には動詞の名前を付けると、1 行が文のように読めます。
const orderCount = orders.length;
const isLoggedIn = Boolean(session);
const user = { firstName: "Ada", lastLogin: null };
function calculateShipping(order) {
// ...
}真偽値には、is、has、can のプレフィックス(isLoggedIn、hasAccess)を付けると、「何についての真偽なのか」という疑問に、誰かが尋ねる前に答えられます。Google のガイドも、真偽値を返すゲッターに同じプレフィックス(isFoo、hasFoo)を使っています。
Google のガイドには、名前の長さについての良いルールもあります。無理のない範囲でできるだけ説明的にし、文字を削って省略しないというものです。errorCount と customerId は合格で、nErr と cstmrId は不合格です。例外は、スコープが 10 行以内の変数で、短いループの i や、points.map((x) => x * 2) の x がそれにあたります。
コレクション、カウント、イベントハンドラー
いくつかのパターンを覚えておくと、名前を予測しやすくなります。配列には複数形(users)、1 つの要素には単数形を使うと、for (const user of users) が自然に読めます。参照用オブジェクトは、キーにちなんで名付け(usersById)、数値は数えているものにちなんで名付けます(userCount)。React では、ドキュメントがイベントに関する一般的な慣習を紹介しています。ハンドラーは handle にイベント名を付けて命名し(handleClick)、ハンドラーを受け取る props は on と大文字で始めます(onClick、onSave)。
クラス、コンストラクター、コンポーネントには PascalCase
new で生成するものは PascalCase にします。React がコンポーネントとして描画するものも同じです。
class ShoppingCart {
addItem(item) {
// ...
}
}
const cart = new ShoppingCart();
function OrderSummary({ order }) {
return <section>{order.id}</section>;
}クラスでは慣習ですが、React では必須です。React のドキュメントによると、コンポーネント名は大文字で始めなければ動作しません。JSX は <section> のような小文字のタグを普通の HTML 要素として扱うからです。TypeScript では、インターフェース、型エイリアス、enum にも同じ PascalCase を使います。
組み込みのものは、これらすべてのお手本になっています。コンストラクターは PascalCase(Map、Promise、Date)、メソッドは camelCase(Object.fromEntries、Array.prototype.flatMap)、固定値は大文字(Math.PI、Number.MAX_SAFE_INTEGER)です。
CONSTANT_CASE を使う場面(と使わない場面)
定数が最も混乱のもとです。const は「定数」という意味ではないからです。変数への再代入を防ぐだけで、その変数が指している配列やオブジェクトの中身は変えられます。2 つの大きなスタイルガイドは、もっと厳しい条件を満たすものにだけ大文字を使います。
- Google:CONSTANT_CASE は、モジュールレベルの値(と静的プロパティ)のうち、ネストした中身まで含めて不変のものに使います。変更しないつもりでいるだけのオブジェクトでは不十分で、関数の中で宣言した定数は lowerCamelCase のままです。
- Airbnb:大文字は任意で、エクスポートされ、
constで宣言され、(ネストしたプロパティも含めて)変わらないと信頼できる値にだけ使います。ファイル内のすべてのconstを大文字にする必要はありません。
// Module level, never changes: capitals
export const MAX_UPLOAD_BYTES = 5 * 1024 * 1024;
export const ORDER_STATUS = Object.freeze({ PENDING: "pending", SHIPPED: "shipped" });
function visibleNames(items) {
const visible = items.filter((item) => !item.hidden); // const, but not a constant
const names = []; // const binding, mutable array
for (const item of visible) names.push(item.name);
return names;
}2 つのガイドは、enum に似たオブジェクトのキーで意見が分かれます。Google は上のように enum のメンバーを CONSTANT_CASE で書き、Airbnb は大文字でエクスポートするオブジェクトの中のキーを小文字にすることを好みます。コードベース全体で同じようにしているなら、どちらでも構いません。もう 1 つ注意点があります。Object.freeze は浅いので、凍結したオブジェクトの中に、変更できるネストしたオブジェクトが残っていることがあります。
private フィールド:アンダースコアではなく # を使う
「private」なメンバーに先頭のアンダースコアを付ける昔ながらの習慣(this._count)は、ヒントにすぎず、誰でもそのプロパティを読み書きできます。Airbnb のガイドは、まさにその理由で、先頭や末尾のアンダースコアを使わないよう述べており、Google の TypeScript ガイドもプレフィックスとサフィックスとしての使用を禁止しています。現代の JavaScript には、本物の private フィールドがあります。
class Counter {
#count = 0;
increment() {
return ++this.#count;
}
}
const counter = new Counter();
counter.increment();
counter.count; // undefined
// counter.#count // SyntaxError outside the class略語:userId か userID か
Google のルールは、略語を普通の単語として扱うことです。customerId、xmlHttpRequest、loadHttpUrl のようになります。Airbnb のルールは逆で、略語はすべて大文字かすべて小文字にします。SMSContainer や httpRequests がその例です。ブラウザー自体も統一されておらず、XMLHttpRequest、innerHTML、getElementById、encodeURIComponent が同じプラットフォームに混在しています。
私たちなら Google のルールを選びます。予測しやすく、単語の境目が見えたままで、ほかのケースのスタイルときれいに変換できるからです。ただし、どれを選ぶかより、一貫していることのほうが大切です。主要なガイドすべての略語のルールは、camelCase と PascalCase の比較で比べています。
API から届く snake_case のデータを扱う
Python、Ruby、SQL データベースを裏側に持つ API は、first_name のようなキーを返してくることがよくあります。それをコード全体に広げてはいけません。データが入ってくる時点で名前を付け替えましょう。分割代入を使えば 1 行で済みます。
const response = await fetch("/api/users/42");
const { first_name: firstName, last_login: lastLogin } = await response.json();ペイロード全体なら、キーを再帰的に変換する小さな関数を方向ごとに書いて、API クライアントの中で呼び出します。1 つの実装をcamelCase の JSON を snake_case に変換する方法で順を追って紹介しています。1 回限りの名前変更なら、当サイトの文字ケース変換ツールで last_login が lastLogin に 1 クリックで変わります。
ESLint で強制する
ESLint の組み込みルール 2 つで、ほとんどをカバーできます。camelcase は、名前の途中にあるアンダースコアを指摘しますが、すべて大文字の定数や、先頭・末尾のアンダースコアは無視します。new-cap は、小文字の名前に new を付けた場合と、大文字で始まる関数を new なしで呼んだ場合を指摘します。
// eslint.config.js
export default [
{
rules: {
camelcase: ["error", { properties: "never" }],
"new-cap": "error",
},
},
];properties: "never" オプションを指定すると、camelcase は data.first_name のような API のフィールドについては文句を言わなくなり、自分で宣言した変数のチェックは続けます。TypeScript のプロジェクトでは、@typescript-eslint/naming-convention がさらに一歩進んで、変数、関数、クラス、型パラメーターなど、識別子の種類ごとに許可する形式を設定できます。Google のルールの全体は Google JavaScript Style Guide にあります。
JavaScript の変数名チェックリスト
- 変数、関数、パラメーター、メソッド、プロパティには camelCase。
- クラス、コンストラクター、React コンポーネント、TypeScript の型、インターフェース、enum には PascalCase。
- CONSTANT_CASE は、変わることのないモジュールレベルの値に使い、すべての
constには使わない。 - アンダースコアのプレフィックスではなく
#privateフィールドを使う。 - 略語のルールは 1 つにして、コントリビューションガイドに書いておく。
- snake_case の API キーは、境界で 1 度だけ変換する。


