浅い凍結と深い凍結
凍結がどの範囲まで及ぶかを理解します。
「浅い凍結と深い凍結」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。
freeze は浅い処理
Object.freeze はオブジェクトの最上位レベルだけを固定します。参照されているネストされたオブジェクトや配列は、完全に変更可能なままです。
これは多くの開発者にとって意外であり、見つけにくいバグの原因になります。
浅い処理の限界を確認する
ネストされたオブジェクトを持つオブジェクトを freeze します。最上位レベルは固定されますが、ネストされたオブジェクトは変更できます。
const user = Object.freeze({
name: 'Ada',
address: { city: 'London' }
});
user.name = 'Grace';
user.address.city = 'Paris';
console.log(user.name);
console.log(user.address.city);ネストされた配列も同様
freeze されたオブジェクト内の配列も保護されません。配列に対して push や pop を実行したり、要素を再代入したりできます。
const state = Object.freeze({ tags: ['a', 'b'] });
state.tags.push('c');
state.tags[0] = 'X';
console.log(state.tags);isFrozen で確認する
ネストされたオブジェクトの isFrozen は false を返し、freeze が内部まで及んでいないことを確認できます。
const obj = Object.freeze({ inner: { v: 1 } });
console.log(Object.isFrozen(obj));
console.log(Object.isFrozen(obj.inner));deepFreeze を作成する
すべてを固定するには、再帰処理を行います。オブジェクトを freeze してから、ネストされた各オブジェクトプロパティを freeze します。これがディープフリーズです。
function deepFreeze(obj) {
for (const key of Object.keys(obj)) {
const value = obj[key];
if (value && typeof value === 'object') {
deepFreeze(value);
}
}
return Object.freeze(obj);
}
const data = deepFreeze({ a: { b: { c: 1 } } });
data.a.b.c = 999;
console.log(data.a.b.c);配列に対する deepFreeze
配列もオブジェクトなので、同じ再帰処理で freeze できます。これにより、どの深さでも push や要素への書き込みが阻止されます。
function deepFreeze(obj) {
for (const key of Object.keys(obj)) {
const value = obj[key];
if (value && typeof value === 'object') deepFreeze(value);
}
return Object.freeze(obj);
}
const state = deepFreeze({ list: [1, 2, 3] });
state.list.push(4);
state.list[0] = 99;
console.log(state.list);ディープフリーズを確認する
ディープフリーズ後は、すべてのネストされたオブジェクトが isFrozen として true を返します。
function deepFreeze(obj) {
for (const key of Object.keys(obj)) {
const v = obj[key];
if (v && typeof v === 'object') deepFreeze(v);
}
return Object.freeze(obj);
}
const o = deepFreeze({ a: { b: 1 } });
console.log(Object.isFrozen(o));
console.log(Object.isFrozen(o.a));循環参照に対処する
オブジェクトが自分自身を参照している場合、単純な再帰処理は永遠にループします。安全に処理するため、すでに freeze されているオブジェクトはスキップしてください。
function deepFreeze(obj) {
if (Object.isFrozen(obj)) return obj;
for (const key of Object.keys(obj)) {
const v = obj[key];
if (v && typeof v === 'object') deepFreeze(v);
}
return Object.freeze(obj);
}
const a = { name: 'a' };
a.self = a;
deepFreeze(a);
console.log(Object.isFrozen(a.self));ディープフリーズのコスト
ディープフリーズはネストされたすべての値を調べるため、大きな構造では時間とメモリのコストがかかります。共有設定や定数など、本当に保護が必要なものだけを freeze してください。
function deepFreeze(obj) {
if (Object.isFrozen(obj)) return obj;
Object.keys(obj).forEach(k => {
const v = obj[k];
if (v && typeof v === 'object') deepFreeze(v);
});
return Object.freeze(obj);
}
const small = deepFreeze({ a: 1, b: { c: 2 } });
console.log('frozen deeply:', Object.isFrozen(small.b));浅い処理で十分な場合
オブジェクトがプリミティブ値だけを保持している場合は、浅い Object.freeze ですでに完全に保護できます。ディープフリーズが必要なのは、ネストされたオブジェクトや配列がある場合だけです。
const flat = Object.freeze({ a: 1, b: 'two', c: true });
flat.a = 100;
console.log(flat.a);
console.log(Object.isFrozen(flat));重要な理由
浅い freeze とディープフリーズの違いを理解すると、freeze されたオブジェクトが完全に不変だと思い込む問題を防げます。ネストされたデータには再帰処理を行ってください。変更の代わりに、次のレッスンでは freeze ではなくコピーを使う不変更新パターンを扱います。
const config = Object.freeze({ db: { host: 'local' } });
config.db.host = 'changed';
console.log('shallow freeze leaked:', config.db.host);クイックチェック
Object.freeze({ a: { b: 1 } }) の後、ネストされた b を変更できますか。
まとめ: 浅い freeze とディープフリーズ
freeze の深さの制限について学びました。
Object.freezeは浅い処理であり、ネストされたオブジェクトや配列は変更可能なままです。- deepFreeze は再帰処理を行い、すべてのレベルを固定します。
- すでに freeze されているオブジェクトをスキップして、循環参照に対処します。
- ディープフリーズにはコストがかかるため、保護が必要なものだけを freeze してください。
よくある質問
「浅い凍結と深い凍結」レッスンは無料ですか?
はい。「浅い凍結と深い凍結」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。
「浅い凍結と深い凍結」で何を学びますか?
凍結がどの範囲まで及ぶかを理解します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
JavaScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「浅い凍結と深い凍結」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJavaScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。