0Pricing
JavaScript Academy · レッスン

ミューテーションを避ける

データを変更せず、コピーを使って処理します。

「ミューテーションを避ける」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。

変更を避ける理由

共有データを変更すると、追跡の難しいバグが発生します。ある場所での変更が、別の場所のコードを予期せず動かしてしまうためです。関数型のスタイルでは、既存の値を変更するのではなく、新しい値を作成すること(イミュータブル性)を重視します。

const original = [1, 2, 3];
const copy = [...original, 4];
console.log(original); // [1, 2, 3]
console.log(copy);     // [1, 2, 3, 4]

スプレッド構文で配列をコピーする

スプレッド演算子...は配列の浅いコピーを作成し、元の配列に触れずに要素を追加できるようにします。

const nums = [1, 2, 3];
const more = [...nums, 4, 5];
console.log(more); // [1, 2, 3, 4, 5]
console.log(nums); // [1, 2, 3]

スプレッド構文でオブジェクトをコピーする

スプレッド構文はオブジェクトにも使えます。同じプロパティに加えて、上書きするプロパティを持つ新しいオブジェクトを生成します。

const user = { name: "Ada", age: 36 };
const older = { ...user, age: 37 };
console.log(older); // { name: "Ada", age: 37 }
console.log(user);  // unchanged

変更を伴わない配列メソッド

新しい配列を返すメソッドを優先してください。map、filter、concat、sliceなどです。push、splice、インプレースのsortのように変更を伴うメソッドは避けてください。

const a = [3, 1, 2];
const sorted = [...a].sort((x, y) => x - y);
console.log(sorted); // [1, 2, 3]
console.log(a);      // [3, 1, 2]

変更せずに追加する

pushの代わりに、スプレッド構文またはconcatで新しい配列を作成してください。

const list = [1, 2];
const added = [...list, 3]; // not list.push(3)
console.log(added); // [1, 2, 3]

変更せずに削除する

spliceの代わりにfilterを使い、要素を除いた新しい配列を作成してください。

const list = [1, 2, 3, 4];
const without3 = list.filter((n) => n !== 3);
console.log(without3); // [1, 2, 4]

項目を変更せずに更新する

1つの要素を変更するには、配列に対してmapを使い、一致する項目に対して新しい値を返します。

const todos = [{ id: 1, done: false }, { id: 2, done: false }];
const updated = todos.map((t) =>
  t.id === 1 ? { ...t, done: true } : t
);
console.log(updated[0].done); // true

浅いコピーと深いコピー

スプレッド構文でコピーされるのは1階層分です。ネストしたオブジェクトは引き続き共有参照になります。ネストしたデータを変更せずに更新するには、変更する各階層でスプレッド構文を使ってください。

const state = { user: { name: "Ada", age: 36 } };
const next = {
  ...state,
  user: { ...state.user, age: 37 }
};
console.log(state.user.age); // 36
console.log(next.user.age);  // 37

安全性のために凍結する

Object.freezeは実行時にオブジェクトの意図しない変更を防ぎ、イミュータブル性を明示します(1階層分のみ)。

const config = Object.freeze({ env: "prod" });
config.env = "dev";       // ignored in non-strict mode
console.log(config.env);  // "prod"

Constはイミュータブル性ではない

よくある混同に注意してください。constが防ぐのは変数の再代入だけで、保持している値の変更ではありません。constで宣言した配列にも、引き続き要素をpushできます。

const arr = [1, 2];
arr.push(3);          // allowed - value mutated
console.log(arr);     // [1, 2, 3]
// arr = [] would throw

メリットのまとめ

イミュータブルな更新によって、参照を比較するだけで変更を簡単に追跡でき、undo/redoが可能になります。また、遠く離れた場所への予期しない影響を防ぎ、純粋関数とも自然に組み合わせられます。

const prev = { count: 0 };
const next = { ...prev, count: 1 };
console.log(prev === next); // false - easy to detect change

確認問題

変更の回避

まとめ

イミュータブル性とは、値を変更するのではなく新しい値を作成することです。スプレッド構文で配列やオブジェクトをコピーし、変更を伴わないmap、filter、concatなどのメソッドを優先してください。ネストしたデータを更新するときは、各階層でスプレッド構文を使います。constが防ぐのは再代入であり、変更ではないことを覚えておきましょう。Object.freezeを使えば実行時の保護も追加できます。イミュータブルな更新により、変更検出と純粋なコードを簡単に実現できます。

よくある質問

「ミューテーションを避ける」レッスンは無料ですか?

はい。「ミューテーションを避ける」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。

「ミューテーションを避ける」で何を学びますか?

データを変更せず、コピーを使って処理します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

JavaScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「ミューテーションを避ける」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJavaScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

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

  1. 純粋関数と副作用
  2. 宣言的なデータ変換
  3. ミューテーションを避ける
  4. ポイントフリースタイル
← JavaScript Academyに戻る