猫の手ツール

Step 1: Web Basics

01. constとletの違いとは?
モダンJSにおける変数宣言の作法

constとletは、値の種類ではなく「同じ変数へ別の値を入れるか」で使い分けます。猫の手ツールの証明写真では、画面の要素への参照と、作り直すCropperや切り抜きCanvasを区別しています。まず短いコードで違いを確かめ、実際の画像編集の状態へつなげます。

1. なぜ var は使われなくなったのか?

JavaScriptの初期から存在していた var には、プログラミング上の大きな「罠」がいくつかありました。最も深刻だったのは「スコープ(変数の有効範囲)」をブロック単位だと思い込んでしまうことです。

var は関数スコープであり、意図しない場所で変数が書き換わってしまうリスク(変数の再宣言が可能など)を抱えていました。これに対して、ES6(ES2015)で導入された const と let は「ブロックスコープ」を採用しており、 で囲まれた範囲内でのみ有効です。これにより、コードの予測可能性が飛躍的に向上しました。

2. const と let の使い分けルール

現在のフロントエンド開発において、推奨されるルールは非常にシンプルです。

  • const (Constant): 再代入が不可能な宣言。一度値を決めたら、その名前の変数を書き換えることはできません。
  • let: 再代入が可能な宣言。ループのカウント変数や、状態が変わるフラグなどに使用します。

同じ変数名に別の値を入れる必要がなければ const を選べます。「再代入しない」という意図が読み手に伝わりますが、配列やオブジェクトの中身まで固定する宣言ではありません。

コードで見る Before / After

【昔の書き方】var による不透明な宣言

var message = "こんにちは";
var message = "さようなら"; // 再宣言できてしまう(バグの元)

if (true) {
  var x = 10;
}
console.log(x); // 10 が出力されてしまう(外に漏れている)

【現在の書き方】const と let による厳格な宣言

const appTitle = "猫の手ツール";
// appTitle = "犬の手"; // ⚠️ Error: Assignment to constant variable.

let counter = 0;
counter += 1; // OK

if (true) {
  const innerVar = "秘密";
}
// console.log(innerVar); // ⚠️ Error: innerVar is not defined(正しくガードされている)

3. 再代入を減らす設計の見通し

サーバー構築の世界でも、最近は「イミュータブル(不変)インフラストラクチャ」が重視されます。一度プロビジョニングしたサーバーの設定は変更せず、変更が必要なら新しく作り直すという考え方です。

JavaScriptの const もこれに似ています。変数の状態が刻一刻と変化する(ミュータブルな)コードは、いつどこでバグが起きたかの追跡が困難です。しかし、基本を const に制限することで、「この変数名は別の値へ再代入されない」という見通しを持って読み進めることができます。インフラの設定ファイルを Git で管理する際の「宣言的」な感覚に近いものがあります。

4. 注意点:const は「完全な不変」ではない

初心者がよくハマるポイントが、オブジェクトや配列を const で宣言した時の挙動です。

const user = { name: "Tanaka" };
user.name = "Sato"; // これはOK!
// user = { name: "Suzuki" }; // これはNG(再代入はできない)

const が禁止しているのはあくまで 「変数そのものへの再代入」 であり、オブジェクトの中身(プロパティ)の変更までは制限しません。ここを勘違いして「const だから中身も変わらないはずだ」と思い込むと、思わぬバグに繋がります。

画像処理の設定で使い分ける

設定オブジェクトを更新するだけなら const のままです。別の設定オブジェクトへ差し替える設計なら let を使います。次の例はブラウザのコンソールで実行できます。

const settings = { quality: 0.8 };
settings.quality = 0.6; // 同じオブジェクトのプロパティを変更
let completed = 0;
completed += 1; // 数値自体を再代入
console.log(settings.quality, completed); // 0.6 1

プロパティの変更も止めたい場合には Object.freeze() などを検討します。ただし凍結は浅く、入れ子のオブジェクトまで自動で不変にはなりません。

証明写真では、要素の参照と編集状態を分ける

履歴書写真メーカーでは、取得した画面要素はconst、作り直すcropperやoriginalCroppedCanvasはletで保持します。constの要素でもclassListは変更できるため、「constだから画面を書き換えられない」という解釈は誤りです。

let cropper = null;
let originalCroppedCanvas = null;
const fileInput = document.getElementById('file-input');
// File入力の中身は変わっても、fileInputへ別要素を再代入する必要はない。

これは本番の宣言をJavaScriptへ簡略化した抜粋です。画像を選び直してCropperを作り直す状態と、同じDOM要素の見た目を変える状態を区別して読みます。切り抜きと出力の関係は証明写真の制作解説で確認できます。

5. まとめ:実務での運用

このサイトのコードを読む時や、新しい画像処理を書く時は、以下の順序で宣言を検討できます。

  1. まずは const で書く。
  2. どうしても再代入が必要になった時だけ let に変更する。
  3. var を含む既存コードは、関数スコープや宣言前の参照への依存を調べてから変更する。

変数宣言を変えるときは、再代入の必要性とスコープを先に確認します。既存のvarを文字置換で変更する前に、宣言前の参照や同名変数への依存を調べてください。

参考資料