こんにちは。現場の最前線でコードを書き続けていると、新人エンジニアから一番よく受ける質問がこれなんです。
「`const`で宣言したのに、中身が書き換えられちゃうんですけど!これってバグじゃないんですか?」
結論から言うと、これはバグではなく、JavaScriptの「仕様」です。でも、最初に出会うと本当に混乱しますよね。「定数って言ったじゃん!」とパソコンの前で叫びたくなる気持ち、痛いほど分かります。
今日は、なぜそんなことが起きるのか。そして、本当に「中身まで一切触らせない」ようにするにはどうすればいいのか。現場で使う知恵を交えて解説しますね。
—
1. 「const」という箱の正体:中身ではなく「住所」を固定しているだけ
まずはイメージからいきましょう。`const`で宣言した変数は、「中身を絶対に変えられない箱」ではなく、「一度決めたら別の場所には引っ越しできない、持ち手付きのバスケット」だと考えてみてください。
例えば、こんなコードがあったとします。
const myBag = { fruit: “リンゴ” };
// 中身を書き換えてみる
myBag.fruit = “みかん”;
console.log(myBag.fruit); // 結果は “みかん” になる!
「あれ?エラーにならないの?」と驚きますよね。
実は、`const`が守っているのは「`myBag`という名前の箱に、他の何かが入らないようにすること」だけなんです。
- `const`の役割: このバスケット(オブジェクト)の「住所」を固定する。
- JavaScriptの優しさ(お節介?): 「住所さえ変わらなければ、バスケットの中にあるリンゴをみかんに取り替えるくらい、いいじゃないか」というスタンス。
つまり、`const`は「中身の書き換え」を禁止しているのではなく、「箱そのものを別の箱に入れ替えること」を禁止しているんです。
const myBag = { fruit: “リンゴ” };
// これはNG! 別のバスケットに持ち替えようとしているからエラーになる
myBag = { fruit: “ブドウ” };
これが、`const`で宣言したオブジェクトが書き換え可能な理由です。
—
2. じゃあ、本当に書き換えてほしくない時はどうする?
「中身もガチガチに固めて、誰にもいじらせたくない!」という時もありますよね。そんな時に使うのが、`Object.freeze()`(オブジェクト・フリーズ)という魔法のメソッドです。
名前の通り、オブジェクトを「冷凍保存」して、変更を一切受け付けない状態にします。
const frozenBag = Object.freeze({ fruit: “リンゴ” });
// 凍らせたので、書き換えようとしても無視される(エラーにはならないことが多い)
frozenBag.fruit = “みかん”;
console.log(frozenBag.fruit); // やっぱり “リンゴ” のまま!
注意点:凍らせるのは「表面」だけ
ここが現場の落とし穴なのですが、`Object.freeze()`は「表面のプロパティ」しか凍らせません。もしオブジェクトの中に別のオブジェクト(入れ子)が入っていたら、その内側は凍らずに書き換えられてしまいます。
「完全に凍らせたい(ディープフリーズ)」という場合は、専用のライブラリ(`Immer`など)を使ったり、再帰的に凍らせる関数を自作したりするのが実務の定石です。ただ、まずは「`Object.freeze()`で表面を凍らせる」という基本を覚えておけば、大抵のケースは大丈夫ですよ。
—
3. なぜ「不変性(イミュータビリティ)」が大事なの?
「わざわざ凍らせるなんて面倒だな」と思うかもしれませんが、これには理由があります。
Webサイトが複雑になると、「誰がいつ、どこでこのデータ書き換えたんだ!?」という犯人探しが非常に難しくなります。不変性(データを書き換えず、新しいデータを作る手法)を守ることで、「このデータは絶対に変わらない」という安心感が生まれ、バグが格段に減るんです。
今のモダンな開発(Reactなど)では、この「データを変更せずに、新しいデータに差し替える」という考え方が当たり前になっています。
—
最後に:つまずくのは、あなたが前に進んでいる証拠
最初は`const`と`Object.freeze`の使い分けなんて、誰だって迷います。現場のベテランだって、うっかりミスをすることはあります。
もし「なぜ書き換わっちゃうんだ!」と悩んだら、こう思い出してください。
「ああ、`const`は住所を固定しているだけで、中身は自由だったんだ。中身も守りたければ、冷凍保存(`freeze`)してあげればいいんだな」と。
JavaScriptは自由度が高い分、最初は戸惑うことも多い言語です。でも、その自由度の高さこそが、今のWebを支える力になっています。一歩ずつ、焦らずに理解していきましょう。あなたのコードが、昨日より少しだけ堅牢になりますように!

コメント