このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
Window: structuredClone() メソッド
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2022年3月.
structuredClone() はWindow のメソッドで、指定された値のディープコピーを、構造化複製アルゴリズムを用いて生成します。
このメソッドでは、元の値の移譲可能オブジェクトを、新しいオブジェクトにクローンするのではなく、移譲することもできます。移譲されたオブジェクトは元のオブジェクトから切り離され、新しいオブジェクトに関連付けられます。元のオブジェクトからはもうアクセスできなくなります。
In this article
構文
structuredClone(value)structuredClone(value, options)引数
value複製されるオブジェクトです。これはあらゆる構造化複製可能型です。
options省略可以下のプロパティを持つオブジェクトです。
transfer
移譲可能オブジェクトの配列で、複製するのではなく移動するオブジェクトを指定します。
返値
返値は元のvalue のディープコピーです。
例外
DataCloneErrorDOMException入力値にシリアライズ可能でない部分があった場合に発生します。
解説
この関数は、 JavaScript の値をディープコピーするために使用することができます。また、以下に示すように、循環参照にも対応しています。
// 値と自分自身への循環参照を持つオブジェクトを作成するconst original = { name: "MDN" };original.itself = original;// 複製するconst clone = structuredClone(original);console.assert(clone !== original); // オブジェクトは同じではない(同一ではない)console.assert(clone.name === "MDN"); // 同じ値を持っているconsole.assert(clone.itself === clone); // 循環参照も保持されている移譲される値
移譲可能オブジェクト(のみ)が複製先のオブジェクトに複製する代わりに移譲することができます。この場合、options 引数のtransfer プロパティを使用します。移譲により、元のオブジェクトは使用不可能になります。
メモ:これが役立つ場面として、バッファー内のデータを保存する前に非同期で検証する場合です。データを保存する前にバッファーが変更されるのを避けるために、バッファーをクローンしてそのデータを検証することができます。また、データを「移譲」すれば、元のバッファーに手を加えようとしても失敗するので、偶発的な悪用を防ぐことができます。
以下のコードは、配列のクローンを作成し、その基礎となるリソースを新しいオブジェクトに移譲する方法を示しています。返値において、元のuInt8Array.buffer はクリアされます。
// 16MB = 1024 * 1024 * 16const uInt8Array = Uint8Array.from({ length: 1024 * 1024 * 16 }, (v, i) => i);const transferred = structuredClone(uInt8Array, { transfer: [uInt8Array.buffer],});console.log(uInt8Array.byteLength); // 0任意の数のオブジェクトを複製し、それらのオブジェクトの任意のサブセットを移譲することができます。例えば、以下のコードでは、渡された値からarrayBuffer1 を移譲しますが、arrayBuffer2 は移譲しません。
const transferred = structuredClone( { x: { y: { z: arrayBuffer1, w: arrayBuffer2 } } }, { transfer: [arrayBuffer1] },);例
>オブジェクトの複製
この例では、配列である 1 つのメンバーを持つオブジェクトを複製します。複製後、それぞれのオブジェクトに変更を加えても、他のオブジェクトには影響しません。
const mushrooms1 = { amanita: ["muscaria", "virosa"],};const mushrooms2 = structuredClone(mushrooms1);mushrooms2.amanita.push("pantherina");mushrooms1.amanita.pop();console.log(mushrooms2.amanita); // ["muscaria", "virosa", "pantherina"]console.log(mushrooms1.amanita); // ["muscaria"]オブジェクトの移譲
この例では、ArrayBuffer を作成し、そのバッファーがメンバーであるオブジェクトを複製し、バッファーを移譲しています。複製したオブジェクトでバッファーを使用することができますが、元のバッファーを使用しようとすると例外が発生します。
// バイト単位のサイズを指定して ArrayBuffer を作成const buffer1 = new ArrayBuffer(16);const object1 = { buffer: buffer1,};// バッファーが格納されているオブジェクトを複製し、それを移譲const object2 = structuredClone(object1, { transfer: [buffer1] });// 複製したバッファーから配列を作成するconst int32View2 = new Int32Array(object2.buffer);int32View2[0] = 42;console.log(int32View2[0]);// 元バッファーから配列を作成すると TypeError が発生const int32View1 = new Int32Array(object1.buffer);仕様書
| Specification |
|---|
| HTML> # dom-structuredclone> |