VIDEO LESSON

JavaScriptのstructuredClone():入れ子のデータを独立してコピーするの解説動画

再生時間 7:53動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

  1. 0:00こんにちは。
  2. 0:00今回はジャバスクリプトのストラクチャードクローンを紹介します。
  3. 0:05入れ子になったデータを、元とは独立した形で深くコピーするグローバル関数です。
  4. 0:10設定画面で入力を変更しても、保存するまでは元の設定を残したい。
  5. 0:15そんな場面では、内側まで独立した編集用データが必要になります。
  6. 0:19単に別の変数へ代入しただけでは、同じデータを指し続けてしまいます。
  7. 0:24この動画では、浅いコピーとの違い、基本の使い方、循環参照の扱い、コピーできない値、
  8. 0:29そして転送オプションまで、実行結果と一緒に学びます。
  9. 0:33身近なコピー手段との住み分けを理解すると、場面ごとに迷わず選べるようになります。
  10. 0:39まず、浅いコピーとの違いを確認します。
  11. 0:42オブジェクトを別の変数へ代入しても、それは同じデータを指しているだけです。
  12. 0:49スプレッド構文で外側だけをコピーしても、内側のオブジェクトは元のものと共有されたままになります。
  13. 0:57そのため、コピー側の内側を変更すると、元のデータまで変わってしまうのです。
  14. 1:03一方、ストラクチャードクローンで作った深いコピーでは、内側のオブジェクトも別物として複製されます。
  15. 1:12コピー側をいくら変更しても、元には影響しません。
  16. 1:16編集用データを作るときに必要なのは、この独立性です。
  17. 1:20この共有の仕組みは参照と呼ばれる考え方で、ジャバスクリプトを学ぶうえでの大切な土台でもあります。
  18. 1:29呼び出し方を確認します。
  19. 1:31第一引数にコピーしたい値を渡し、第二引数のオプションは省略できます。
  20. 1:36戻り値はコピーされた値で、オブジェクトを渡した場合は、元とは別のオブジェクトになります。
  21. 1:43注意したいのは、処理が同期的である点です。
  22. 1:47戻り値はプロミスではなく、その場でコピーが完成します。
  23. 1:51大量のデータを頻繁にコピーすると、その間、呼び出し側の処理が待たされてしまいます。
  24. 1:58そのため、コピーは編集開始時など、必要なタイミングと範囲に絞って使うのが基本です。
  25. 2:05対応しているかどうかは、関数として存在するかを実行前に確かめることもできます。
  26. 2:11記事の中心となる例を見ます。
  27. 2:13ユーザー名と通知設定を持つプロフィール、タグの配列、そして更新日時を持つ設定オブジェクトを用意します。
  28. 2:21これをストラクチャードクローンでコピーし、編集用データを作ります。
  29. 2:27そのうえで、コピー側だけ、通知をオフにし、タグを追加し、日時を一日進めます。
  30. 2:33ポイントは、変更がすべてコピー側に閉じていることです。
  31. 2:37元の設定は手つかずで残るため、ユーザーがキャンセルすれば、編集用データを捨てるだけで済みます。
  32. 2:45保存が決まったときだけ、編集結果を反映すればよいのです。
  33. 2:49この形は、フォームの編集画面で特によく使われる、実務に近いパターンです。
  34. 2:55実行結果を読みます。
  35. 2:57元の通知はトゥルーのまま、編集用の通知だけがフォルスになっています。
  36. 3:02タグも、元はジャバスクリプトだけですが、編集用にはノード・ジェイエスが追加されています。
  37. 3:09日時も、元は九月一日、編集用は九月二日と分かれました。
  38. 3:13さらに大切なのは、日時が文字列に化けていない点です。
  39. 3:17コピー後もデートとして扱え、日時のメソッドをそのまま使えます。
  40. 3:22内側のプロフィールが元と別物であることも確認できました。
  41. 3:26この出力はノード・ジェイエスの実機でも確認済みで、記事の期待出力と完全に一致しています。
  42. 3:33ユーティーシーで日時をそろえているため、この結果は実行環境の地域設定に左右されません。
  43. 3:40少し特殊な例として、循環参照を見ます。
  44. 3:43オブジェクトが自分自身を参照しているデータを、循環参照と呼びます。
  45. 3:47文字列化によるコピーでは、この形はエラーになりがちです。
  46. 3:52しかしストラクチャードクローンは、循環参照をそのままコピーできます。
  47. 3:57コピーは元とは別物であり、コピー側の自己参照は、コピー自身を正しく指します。
  48. 4:02元を指し続けることもありません。
  49. 4:04結果は順にトゥルー、トゥルー、フォルスとなり、実機でも確認済みです。
  50. 4:09循環をほどく処理を自分で書く必要がないのは、この関数の大きな強みです。
  51. 4:15同じオブジェクトへの参照が複数ある場合も、その関係はコピー側で正しく保たれます。
  52. 4:20コピーできる値の範囲を確認します。
  53. 4:23通常のオブジェクトや配列だけでなく、日時を表すデート、キーと値の組を保つマップ、
  54. 4:28重複のない集合であるセット、正規表現なども対象です。
  55. 4:33数値や文字列のような基本的な値は、そのままコピーされます。
  56. 4:37文字列化を経由する昔ながらの方法では、日時が文字列になったり、マップやセットが壊れたりしましたが、
  57. 4:42この関数なら型を保ったまま複製できます。
  58. 4:47ただし、ブラウザー専用のオブジェクトまで、ノード・ジェイエスで同じように扱えるわけではありません。
  59. 4:55環境をまたぐ場合は、共通して使える値に絞ってください。
  60. 4:59対応範囲の広さが、単純な文字列化によるコピーとの大きな違いになっています。
  61. 5:04失敗例を確認します。
  62. 5:06設定値と一緒に、保存処理のような関数を持つオブジェクトを渡すと、コピーは成功しません。
  63. 5:12関数だけを無視して残りをコピーするのではなく、呼び出し全体が失敗し、データクローンエラーという名前の例外が発生します。
  64. 5:21例外は同期的に発生するため、トライ・キャッチで捕まえることができます。
  65. 5:27実務では、テーマのようなデータと、保存処理のような振る舞いを分け、データ側だけをコピーする設計にすると扱いやすくなります。
  66. 5:36想定外の例外まで握りつぶさず、名前を確認してから処理する習慣も大切です。
  67. 5:42シンボルを含めた場合も、同様に例外になります。
  68. 5:46コピー前に中身を見直しましょう。
  69. 5:48もう一つの注意点は、振る舞いまでは複製されないことです。
  70. 5:52独自に作ったクラスのインスタンスを渡しても、メソッドを持った同じ種類のインスタンスにはなりません。
  71. 5:58プロトタイプやプライベートな要素、プロパティの読み取り専用といった細かな設定も、
  72. 6:01保持されません。
  73. 6:04正規表現の検索位置も、コピーでは引き継がれません。
  74. 6:08ドムノードも対象外です。
  75. 6:09つまり、この関数が複製するのは、あくまでデータの構造です。
  76. 6:13コピーしたいものがデータなのか、振る舞いを持つインスタンスなのかを、先に判断してください。
  77. 6:19読み取り専用だった項目が、コピー側では書き換え可能になる点も、見落としやすい変化です。
  78. 6:24最後に、転送オプションを押さえます。
  79. 6:27第二引数にトランスファーを指定すると、指定した転送可能な資源が、コピーではなく移動になります。
  80. 6:34バイト配列のバッファーを転送する例では、転送先では中身を読めますが、元のバッファーは切り離され、
  81. 6:38長さがゼロになります。
  82. 6:42指定するのは配列そのものではなく、そのバッファーである点にも注意してください。
  83. 6:48編集前のデータを残したい今回のような用途では、このオプションは省略するのが正解です。
  84. 6:54転送は、元を手放してよい場面専用の仕組みと覚えてください。
  85. 6:59同じバッファーを別のビューが参照している場合、そのビューにも影響が及びます。
  86. 7:04まとめです。
  87. 7:05ストラクチャードクローンは、入れ子のデータを独立して深くコピーする関数で、
  88. 7:10循環参照や日時、マップなども扱えます。
  89. 7:14導入時の判断は三つです。
  90. 7:16まず、コピー対象を通常のデータに絞り、関数や独自クラスが混ざっていないか確認すること。
  91. 7:23次に、編集開始など必要なタイミングに絞って呼び出し、毎回全体をコピーし続けないこと。
  92. 7:30そして、履歴機能に使う場合は、保存件数や対象範囲を先に決めることです。
  93. 7:36練習として、小さな設定オブジェクトをコピーし、内側を変更しても元が変わらないことを確かめてみてください。
  94. 7:44お疲れさまでした。
  95. 7:46小さな例で確かめる習慣が、共有や例外による思わぬ不具合を未然に防いでくれます。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

structuredClone()で入れ子のオブジェクトを深くコピーする方法を解説。ブラウザーとNode.jsの対応、実行手順、循環参照、コピーできない値、転送時の注意点をコードで学びます。

解説記事・サンプルコードを読む:JavaScriptのstructuredClone():入れ子のデータを独立してコピーする →