logo

ネストされたオブジェクトのコピーは structuredClone を使おう

2025-06-30
a month ago

開発環境

  • Node.js 18以降(structuredCloneがグローバルに利用可能)
  • 任意のブラウザ(Chrome 98+, Firefox 94+, Edge 98+, Safari 15.4+ で対応)
  • エディタ:Visual Studio Code 等

前提

JavaScriptではオブジェクトのコピーを行う際に、浅いコピー(shallow copy)と深いコピー(deep copy)の違いが重要になります。

特にネストされたオブジェクトを扱う場合、浅いコピーでは内部のオブジェクトまで複製されず、参照が残るため予期せぬバグの原因になります。

そのような問題を防ぐために、近年では標準で提供されている structuredClone の活用が推奨されつつあります。

本題

従来のコピー方法の落とし穴

よくあるオブジェクトコピーの手法としては、Object.assign() やスプレッド構文(...)があります。これらは浅いコピーしかできません。

例:Object.assign() の場合

const original = {
  user: {
    name: "Taro",
    age: 30
  }
};

const copy = Object.assign({}, original);
copy.user.age = 31;

console.log(original.user.age); // 31(←意図しない変更)

例:スプレッド構文の場合

const original = {
  user: {
    name: "Taro",
    age: 30
  }
};

const copy = { ...original };
copy.user.age = 31;

console.log(original.user.age); // 31(←こちらも変わってしまう)

このように、ネストされたプロパティ(user オブジェクトなど)は参照が共有されてしまうため、コピー元にも影響を及ぼします。

structuredClone を使えば解決!

structuredClone を使えば、オブジェクトを再帰的にディープコピーできます。これにより、ネストされたプロパティも安全に複製されます。

使用例

const original = {
  user: {
    name: "Taro",
    age: 30
  }
};

const copy = structuredClone(original);
copy.user.age = 31;

console.log(original.user.age); // 30(←安全!コピー元は変わらない)

利点

  • ディープコピーが簡単にできる
  • JSONでは扱えない Date, Map, Set などもコピー可能
  • JSON.stringify/parseの代替としても優秀(循環参照も扱える)

注意点

  • 一部の特殊な型(function, DOMノード, undefined など)はコピーできません。
  • 古いブラウザではサポートされていないため、必要に応じてポリフィルや代替手段の検討が必要です。

さいごに

ネストされたオブジェクトのコピーは一見簡単そうですが、浅いコピーでは意図しないバグを招く危険があります。

従来の Object.assign() やスプレッド構文では不十分なケースが多いため、今後は structuredClone を積極的に活用していくのが安全です。

開発者として安全性と保守性を重視するなら、「とりあえず structuredClone」で良い時代になっています。

参照