ネストされたオブジェクトのコピーは 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」で良い時代になっています。