「連番生成」ユーティリティは何に使うのか
連番生成は、「1, 2, 3, 4, … と増えていく番号を、安全に・簡単に振るための仕組み」です。
業務コードでは、次のような場面でよく使います。
テーブルの行 ID(画面内だけで一意ならよい)
一時オブジェクトの識別子
ログの通し番号
「何番目の処理か」を分かるようにするためのカウンタ
毎回「どこかに let counter = 0 と書いて counter++ する」のもアリですが、
きちんとユーティリティとして切り出しておくと、
「どこで何の連番を振っているか」が分かりやすくなり、バグも減ります。
一番シンプルな連番生成:ただのカウンタ変数
まずは一番素朴な形から見てみます。
let counter = 0;
function nextId() {
counter += 1;
return counter;
}
console.log(nextId()); // 1
console.log(nextId()); // 2
console.log(nextId()); // 3
JavaScriptこの nextId は呼ばれるたびに 1, 2, 3… と増えていきます。
仕組み自体はとても簡単です。
ただし、この形には弱点があります。counter がグローバルに露出しているので、
他のコードから勝手に書き換えられてしまう可能性があります。
counter = 9999; // 誰かがこう書いたら、次の ID が 10000 から始まってしまう
JavaScript業務コードでは、こういう「勝手に触られて壊れる状態」はできるだけ減らしたいので、
次のステップとして「カウンタを閉じ込める」形に進みます。
クロージャを使った「安全な連番生成器」
連番生成の定番パターンは、「カウンタを関数の中に閉じ込める」ことです。
これにはクロージャを使います。
function createSequence(start = 1) {
let current = start - 1;
return function next() {
current += 1;
return current;
};
}
JavaScriptこの createSequence は、「連番を生み出す関数」を作る工場のようなものです。
使い方を見てみましょう。
const nextRowId = createSequence(1);
console.log(nextRowId()); // 1
console.log(nextRowId()); // 2
console.log(nextRowId()); // 3
JavaScriptここでの重要ポイントを丁寧に整理します。
createSequence が呼ばれたときに、current という変数が一つだけ作られるnext 関数は、その current を覚えたまま返される(これがクロージャ)next を呼ぶたびに current が 1 ずつ増えて、その値が返るcurrent は createSequence の外からは直接触れない
つまり、「連番の状態(current)を外から隠しつつ、番号だけを取り出せる」仕組みになっています。
これが、業務で使える「安全な連番生成」の基本形です。
複数種類の連番を独立して持つ
クロージャを使うと、「用途ごとに別々の連番」を簡単に持てます。
const nextUserId = createSequence(1);
const nextOrderId = createSequence(1000);
console.log(nextUserId()); // 1
console.log(nextUserId()); // 2
console.log(nextOrderId()); // 1000
console.log(nextOrderId()); // 1001
JavaScriptnextUserId と nextOrderId は、それぞれ別の current を持っています。
ユーザー ID と注文 ID のカウンタが混ざることはありません。
ここでの深掘りポイントは、
「createSequence を呼ぶたびに“独立したカウンタ”が生まれる」という感覚です。
これを理解すると、「画面ごと」「機能ごと」に連番を分ける設計が自然にできるようになります。
連番にプレフィックスを付けて「意味のある ID」にする
単なる数字だけだと、ログやデバッグ時に「この 3 って何の 3?」となりがちです。
そこで、文字列のプレフィックスを付けておくと、用途が分かりやすくなります。
function createIdSequence(prefix = "id", start = 1) {
const next = createSequence(start);
return function nextId() {
const n = next();
return `${prefix}_${n}`;
};
}
JavaScript使い方はこうです。
const nextTempId = createIdSequence("temp", 1);
const nextRowId = createIdSequence("row", 1);
console.log(nextTempId()); // "temp_1"
console.log(nextTempId()); // "temp_2"
console.log(nextRowId()); // "row_1"
console.log(nextRowId()); // "row_2"
JavaScriptこれで、ID を見ただけで「これは一時 ID」「これは行 ID」と分かるようになります。
業務ログやデバッグでの読みやすさが一気に上がります。
実務での具体的な利用イメージ
画面内の「仮 ID」としての連番
例えば、まだサーバーに保存していない行データに ID を振りたいとき。
const nextRowId = createIdSequence("row");
const rows = [];
rows.push({ id: nextRowId(), name: "行1" });
rows.push({ id: nextRowId(), name: "行2" });
console.log(rows);
// [
// { id: "row_1", name: "行1" },
// { id: "row_2", name: "行2" },
// ]
JavaScriptサーバーから本物の ID が返ってきたら、この仮 ID と紐づけて置き換える、というパターンがよくあります。
ログの通し番号としての連番
ログを見やすくするために、「この処理の中で何番目のステップか」を連番で出すこともできます。
const nextStepNo = createSequence(1);
function logStep(message) {
const no = nextStepNo();
console.log(`[STEP ${no}] ${message}`);
}
logStep("開始");
logStep("API 呼び出し");
logStep("結果をパース");
logStep("完了");
JavaScriptログはこうなります。
[STEP 1] 開始
[STEP 2] API 呼び出し
[STEP 3] 結果をパース
[STEP 4] 完了
これだけで、「どの順番で何が起きたか」がかなり追いやすくなります。
連番生成で気をつけたいポイント
一つだけ意識しておいてほしいのは、
「連番は“そのプロセスの中だけで一意”という前提で使う」ということです。
ブラウザをリロードしたらカウンタはリセットされます。
サーバーのプロセスが再起動したら、また 1 から始まります。
なので、
画面内の一時 ID
一つの処理フローの中での通し番号
のような「ローカルな一意性」には連番が向いていますが、
システム全体で絶対にかぶってはいけない ID
複数サーバー間で共有する主キー
のような用途には、UUID やランダム ID の方が適しています。
この「連番の守備範囲」を理解しておくと、
どこで連番を使い、どこで UUID を使うべきかの判断がしやすくなります。
小さな練習で感覚をつかむ
最後に、次のようなことを自分で試してみてください。
createSequence を使って、
「ユーザー用」「注文用」「ログ用」の 3 種類の連番を作る
それぞれを何回か呼んで、番号が混ざらずに増えていくことを確認する
そのうえで、createIdSequence を使ってuser_1, user_2, order_1000, order_1001 のような ID を実際に生成してみると、
「連番生成ユーティリティを“用途ごとに分けて使う”感覚」がしっかり身についてきます。
ここまで来れば、あなたはもう
「とりあえず let n = 0」から卒業して、
「設計された連番生成」を業務コードに組み込める状態です。
