0Pricing
JavaScript Academy · レッスン

浅い凍結と深い凍結

凍結がどの範囲まで及ぶかを理解します。

「浅い凍結と深い凍結」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Object.freeze と seal
  2. 浅い凍結と深い凍結
  3. イミュータブルな更新パターン
  4. 深いコピーのための structuredClone
← JavaScript Academyに戻る