TypeScript | 基礎文法:変数・基本型 – let / const の違い

JavaScript
スポンサーリンク

let と const は「変えられるかどうか」を表すスイッチ

まず大事な前提として、TypeScript(というかモダンなJavaScript)では、変数宣言に var ではなく letconst を使います。
この2つの違いを一言でいうと、let は「あとで中身を変えていい変数」、const は「一度決めたら中身を変えない(変えられない)変数」です。

ここでいう「変えられない」は、「再代入できない」という意味です。
たとえば、次のようなコードを見てください。

let count = 1;
count = 2;      // OK(let は再代入できる)

const name = "Taro";
name = "Hanako"; // エラー(const は再代入できない)
TypeScript

let で宣言した count は、あとから 2 に変えても問題ありません。
一方、const で宣言した name は、最初に "Taro" を入れた時点で固定され、別の値を代入しようとするとコンパイルエラーになります。

「この変数は途中で変わるのが前提か?」「一度決めたら変えない前提か?」
この意図をコードに刻むのが、letconst の一番大事な役割です。


TypeScript だからこそ意識したい「再代入しない」設計

const をデフォルトにして、必要なときだけ let にする

天才プログラマー目線でいうと、「特別な理由がない限り const を使う」が基本です。
理由はシンプルで、「変わらないものは変わらないと宣言しておいた方が、バグが入り込みにくい」からです。

たとえば、次の2つを比べてみてください。

let taxRate = 0.1;
TypeScript
const taxRate = 0.1;
TypeScript

どちらも動きますが、let だと「どこかで taxRate を書き換えてしまう」可能性があります。
const にしておけば、「これは固定の税率なんだな」と読み手にも伝わるし、うっかり書き換えようとしたときにコンパイルエラーで止めてくれます。

TypeScriptは「意図を型や宣言で表現する」言語なので、「変えないつもりの値は const にする」というのは、かなり重要な設計のクセになります。


「変えられない」の中身をもう少し深掘りする

const でも「オブジェクトの中身」は変えられる

ここでひとつ、初心者がよく引っかかるポイントがあります。
const は「再代入できない」だけであって、「中身が完全に不変になる」わけではありません。

オブジェクトや配列で見てみましょう。

const user = {
  name: "Taro",
  age: 20
};

user.name = "Hanako";  // これは OK
// user = { name: "Jiro", age: 30 }; // これは NG(再代入)
TypeScript

user という「箱」自体は const なので、別のオブジェクトを丸ごと代入し直すことはできません。
でも、その箱の中身(プロパティ)は変更できます。

配列も同じです。

const scores = [80, 90];

scores.push(100); // OK(中身の操作)
scores[0] = 50;   // OK
// scores = [1, 2, 3]; // NG(再代入)
TypeScript

ここでのポイントは、「const は参照先(どのオブジェクトを指しているか)を固定するだけで、そのオブジェクトの中身まで凍結するわけではない」ということです。
「箱は変えないけど、中身は変えるかもしれない」という状況は、実務でもよくあります。


let を使うべき典型的な場面

カウンタやループ変数のように「変化させる前提」の値

let が本領発揮するのは、「値が時間とともに変化するのが前提」の場面です。
たとえば、ループのカウンタや、合計値を計算していく変数などです。

let sum = 0;

for (let i = 0; i < 5; i++) {
  sum += i;
}

console.log(sum); // 0 + 1 + 2 + 3 + 4 = 10
TypeScript

ここで sumi を const にすることはできません。
sum は毎回足し込んでいくし、i もループのたびに変わっていきます。

こういう「変化させること自体が目的」の変数には、迷わず let を使います。
逆に言うと、「本当に変える必要があるのか?」と一度立ち止まって考えてから let を使う、くらいの感覚がちょうどいいです。


TypeScript の型と組み合わせた let / const のイメージ

型注釈と一緒に書いてみる

TypeScriptでは、letconst に型注釈を付けることができます。

let age: number = 20;
age = 21; // OK

const name: string = "Taro";
// name = "Hanako"; // エラー
TypeScript

ここでは、age は「数値で、あとから変わるかもしれない値」、name は「文字列で、変えない前提の値」という意図が、let / const と型注釈の両方から読み取れます。

TypeScriptのコンパイラは、let / const と型情報を組み合わせて、「この変数はこういう使われ方をするはずだ」という前提でコードをチェックしてくれます。
たとえば、const name: string = "Taro"; と書いておけば、あとから name = 123; のような「型も意図もおかしい」代入をしようとしたときに、しっかりエラーで止めてくれます。


スコープの話は「次の一歩」として意識しておく

letconst には、「ブロックスコープ」というもうひとつ大事な特徴があります(var との違い)。
これは、「if や for の中で宣言した変数は、そのブロックの外からは見えない」という性質です。

if (true) {
  let x = 1;
  const y = 2;
}
// console.log(x); // エラー
// console.log(y); // エラー
TypeScript

この性質のおかげで、「意図せず外側の変数を上書きしてしまう」といった事故が起きにくくなります。
ただ、ここは少し話が広がるので、「let / const はブロックの中だけ有効なんだな」くらいのイメージを持っておけば、今は十分です。


初心者がまず身につけたい感覚

結論として、こういう感覚を持っておくと、かなりいいスタートが切れます。

「まず const で書いてみる」
「本当に値を変える必要があるところだけ let にする」

これだけで、コードの意図がぐっとクリアになり、TypeScriptの型チェックとも相性のいい書き方になります。
そして、const でも「オブジェクトの中身は変えられる」というポイントを覚えておくと、「あれ、const なのに書き換えていいの?」というモヤモヤも減っていきます。

タイトルとURLをコピーしました