Object.freeze は「オブジェクトを氷漬けにする魔法」
Object.freeze は、
「このオブジェクト、もう二度と書き換えられないようにしたい」
というときに使う機能です。
一言でいうと、
そのオブジェクトに対して
「追加・変更・削除」
すべて禁止する
という“完全ロック”です。
const config = {
apiUrl: "https://example.com",
timeout: 5000,
};
Object.freeze(config);
config.timeout = 10000; // 無視される(strict モードならエラー)
config.newProp = "test"; // 追加されない
delete config.apiUrl; // 消えない
console.log(config);
// { apiUrl: "https://example.com", timeout: 5000 }
JavaScriptconst と Object.freeze の違いをはっきりさせる
const は「変数の再代入禁止」、freeze は「中身の変更禁止」
ここ、めちゃくちゃ混ざりやすいポイントです。
const user = {
name: "太郎",
};
user.name = "花子"; // これは OK
// user = {} // これは NG(再代入)
JavaScriptconst は
「変数 user に“別のオブジェクト”を入れ直すのを禁止する」
だけであって、
オブジェクトの中身(プロパティ)は普通に変えられます。
一方、Object.freeze は
「そのオブジェクトの中身を一切変えられなくする」 ものです。
const user = {
name: "太郎",
};
Object.freeze(user);
user.name = "花子"; // 変更されない
console.log(user.name); // 太郎のまま
JavaScriptここが重要です。
「変数を守るのが const、オブジェクトの中身を守るのが Object.freeze」
と分けて覚えるとスッキリします。
freeze すると何ができなくなるのか
追加・変更・削除、全部 NG
Object.freeze(obj) されたオブジェクトに対しては、
次のことができなくなります。
新しいプロパティの追加
既存プロパティの値の変更
既存プロパティの削除
実際の挙動を見てみましょう。
"use strict";
const settings = {
theme: "dark",
language: "ja",
};
Object.freeze(settings);
// 変更
settings.theme = "light"; // TypeError(strict モード)
// 追加
settings.fontSize = 16; // TypeError(strict モード)
// 削除
delete settings.language; // TypeError(strict モード)
JavaScriptstrict モードでない場合は、
エラーにはならず「静かに無視」されます。
ここが重要です。
「freeze したら“変えようとしても変わらない”」
ということを前提に設計する。
strict モードなら“変えようとした瞬間にバグに気づける”。
Freeze は「浅い凍結」である(ここが落とし穴)
ネストされたオブジェクトの中身は凍らない
Object.freeze は、
「そのオブジェクトの“表面”だけを凍らせる」 ものです。
const config = {
api: {
url: "https://example.com",
timeout: 5000,
},
};
Object.freeze(config);
config.api = { url: "https://other.com" }; // これは無効(上書きできない)
config.api.timeout = 10000; // これは通ってしまう!
console.log(config.api.timeout); // 10000
JavaScriptなぜか?
config 自体は凍っているので、config.api という「プロパティの付け替え」はできません。
しかし、config.api が指している
「中のオブジェクト」は凍っていないので、
その中の timeout は普通に書き換えられてしまいます。
ここが超重要です。Object.freeze は“シャローフリーズ(浅い凍結)”。
ネストされたオブジェクトまで自動で凍ってくれるわけではない。
「本当に全部凍らせたい」場合の考え方(概念だけ)
再帰的に freeze する、という発想
初心者の段階ではコードを覚える必要はありませんが、
考え方だけ紹介しておきます。
「ネストされたオブジェクトも含めて全部凍らせたい」
という場合は、
そのオブジェクトの全プロパティを調べる
値がオブジェクトなら、そこにも Object.freeze をかける
それを再帰的に繰り返す
という「deepFreeze」的な関数を自分で用意します。
大事なのは、
「freeze だけでは“完全な不変”にはならない」
という事実を知っておくことです。
Freeze をどんなときに使うと気持ちいいか
「絶対に変わってほしくない設定・定数」に向いている
例えば、アプリ全体で使う設定オブジェクト。
const CONFIG = {
API_URL: "https://example.com",
TIMEOUT: 5000,
};
Object.freeze(CONFIG);
JavaScriptこの CONFIG がどこかで書き換えられると、
アプリ全体が予期せぬ動きをするかもしれません。
そこで Object.freeze を使っておくと、
「誰かがうっかり CONFIG.TIMEOUT = 100; と書いても、
実際には変わらない(strict モードならその場でエラー)」
という安全装置になります。
ここが重要です。
freeze は「このオブジェクトは“読み取り専用”だ」という意思表示。
“変わらないこと”を前提に設計したいデータに使う。
初心者として「Freeze(凍結)」で本当に押さえてほしいこと
最後に、要点だけぎゅっとまとめます。
Object.freeze(obj) は、そのオブジェクトを「変更不可」にする
プロパティの追加・変更・削除ができなくなる
ただし“浅い凍結”であり、ネストされたオブジェクトの中身は変えられてしまうconst は「変数の再代入禁止」、freeze は「オブジェクトの中身の変更禁止」
まずは、こんなコードを自分で打ってみてください。
"use strict";
const config = {
mode: "production",
};
Object.freeze(config);
config.mode = "development"; // ここで何が起きるか確認してみる
console.log(config.mode);
JavaScript「変えたつもりなのに変わらない」
「strict モードだとエラーになる」
その感覚を一度ちゃんと味わうと、Object.freeze は単なる“便利メソッド”ではなく、
「データを守るための設計ツール」 として見えてきます。
