VIDEO LESSON

JavaScriptのObject.seal():値を更新しながらオブジェクトの項目を固定するの解説動画

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

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

  1. 0:00こんにちは。
  2. 0:01今回はジャバスクリプトのオブジェクト・シールを紹介します。
  3. 0:06これは、オブジェクトの項目の構成を固定するメソッドです。
  4. 0:10たとえば、処理の進み具合を表すデータでは、総件数や完了件数、状態といった項目が決まっています。
  5. 0:18値は途中で変わりますが、必要な項目が途中で消えてしまうと、集計結果がおかしくなります。
  6. 0:26シールを使えば、項目の追加と削除を止めたまま、既存の値だけを更新できます。
  7. 0:32項目が決まっている共有データで、事故を防ぐための仕組みだと考えてください。
  8. 0:38この先では、できる操作とできない操作を、実行結果と一緒に一つずつ確かめていきます。
  9. 0:46まず動作環境です。
  10. 0:47オブジェクト・シールはブラウザー専用の機能ではなく、ジャバスクリプトの標準の仕組みです。
  11. 0:54二千十五年七月以降、主要ブラウザーを横断して利用できる機能とされており、
  12. 0:59現在のクローム、エッジ、ファイアフォックス、サファリで使えます。
  13. 1:04ノード・ジェイエスでも動作し、追加のパッケージは必要ありません。
  14. 1:09記事の実行環境は現行ブラウザーとノード・ジェイエス二十二以降です。
  15. 1:14古い環境へ入れる場合は、タイプオブで関数として存在するかを確認してから使ってください。
  16. 1:20外部ライブラリも、画面操作も、通信も使わないサンプルなので、どちらの環境でも同じ手順で試せます。
  17. 1:27基本の書き方を見ましょう。
  18. 1:30オブジェクト・シールに、固定したいオブジェクトを一つ渡すだけです。
  19. 1:36戻り値は、引数に渡したのと同じオブジェクトです。
  20. 1:40新しいコピーが作られるわけではありません。
  21. 1:44封印すると、そのオブジェクト自身のプロパティはすべて、コンフィギュラブルがフォルスになり、
  22. 1:50追加も削除も、属性の変更もできなくなります。
  23. 1:56一方で、書き込み可能な既存プロパティの値は、そのまま更新できます。
  24. 2:02つまり、形は固定、値は可変です。
  25. 2:05この二つの顔を押さえることが、理解の出発点になります。
  26. 2:10封印できたかどうかは、オブジェクト・イズシールドに渡すと、トゥルーかフォルスかで確認できます。
  27. 2:18封印する前に大切な準備があります。
  28. 2:21後から項目を追加できないので、必要な項目はすべて先に用意しておく必要があります。
  29. 2:27たとえば完了時刻のように、後で値が決まる項目も、最初はヌルを入れて場所だけ確保しておきます。
  30. 2:34また、封印は値の正しさを保証しません。
  31. 2:36件数を入れる場所に文字列を代入しても、書き込み可能なら更新できてしまいます。
  32. 2:42数値の範囲や状態名のチェックは、更新用の関数で別に行ってください。
  33. 2:47さらに、同じオブジェクトを別の変数から参照している場合、その変数にも封印の影響が及びます。
  34. 2:54封印は、オブジェクトを作るタイミングで一度だけ行う設計にすると、運用のルールが分かりやすくなります。
  35. 3:02ここから実例です。
  36. 3:03進捗情報を表すオブジェクトを用意します。
  37. 3:06中身は、総件数が三、完了件数がゼロ、状態がウェーティング、そして担当者を持つ詳細オブジェクトです。
  38. 3:14このオブジェクトにオブジェクト・シールを適用し、戻り値を別の変数で受け取ります。
  39. 3:20実行すると、戻り値と元のオブジェクトが同一かどうかはトゥルーになります。
  40. 3:25つまり封印は、コピーを作る処理ではなく、渡したオブジェクトそのもののルールを変える処理です。
  41. 3:32ブラウザーのコンソールでも、ノード・ジェイエスのファイル実行でも、同じコードがそのまま動きます。
  42. 3:39ここで使う進捗データは、この後の削除や追加の実験でも、そのまま使い続けます。
  43. 3:45次に、できる操作とできない操作を比べます。
  44. 3:48まず、完了件数を一に、状態をランニングに書き換える更新は成功します。
  45. 3:54次に、完了件数をデリートで削除しようとすると、タイプエラーが発生します。
  46. 3:59さらに、開始日時という新しい項目を追加しようとしても、やはりタイプエラーになります。
  47. 4:06サンプルでは、関数の中でストリクトモードを有効にし、エラーをキャッチして名前だけを表示しています。
  48. 4:13失敗しても処理を止めずに、残りの確認へ進める構成です。
  49. 4:17削除されなかったことと、追加されなかったことは、次の出力で確かめます。
  50. 4:22なお、代入による追加が通常モードでは例外にならない場合がある点は、後のセクションで改めて説明します。
  51. 4:30期待出力を順に確認しましょう。
  52. 4:32最初に、同一オブジェクトであることがトゥルーと出ます。
  53. 4:37次に進捗は一スラッシュ三、状態はランニングと表示され、更新が成功したことが分かります。
  54. 4:43続いて、削除と追加はどちらもタイプエラーです。
  55. 4:47その後も完了件数は一のまま残り、追加しようとした項目は存在しません。
  56. 4:52最後に、詳細オブジェクトへのノート追加は成功し、チェック済みと表示されます。
  57. 4:58この最後の一行が、入れ子の注意点につながります。
  58. 5:02エラーメッセージの全文は環境で異なるため、コードでは例外の名前だけを比べています。
  59. 5:08ブラウザーで実行すると、コンソールにアンディファインドが追加で表示されることがありますが、
  60. 5:13これはログとは別の評価結果です。
  61. 5:18失敗を見落とさないための注意です。
  62. 5:20通常モードでは、封印済みオブジェクトへの追加などが、例外を出さずに静かに失敗することがあります。
  63. 5:27処理が止まらないので、追加できたと思い込む事故につながります。
  64. 5:32サンプルがストリクトモードを明記しているのは、この失敗を例外として目に見える形にするためです。
  65. 5:38ジャバスクリプトのモジュールは自動的にストリクトモードになりますが、環境による差を避けるため、
  66. 5:43例では関数の中に明記しています。
  67. 5:48実務では、想定外の例外まで握りつぶさず、原因を追える形にしてください。
  68. 5:53例外の種類を確認してから処理を続けるのか、そのまま呼び出し元へ伝えるのかは、
  69. 5:56事前に決めておくとよいでしょう。
  70. 6:00入れ子、つまりネストしたオブジェクトの扱いも重要です。
  71. 6:05外側を封印しても、内側のオブジェクトに封印は自動で広がりません。
  72. 6:09サンプルでも、詳細オブジェクトへ新しい項目を追加できてしまいました。
  73. 6:15内側も固定したい場合は、内側に対して個別にオブジェクト・シールを適用する必要があります。
  74. 6:21ただし、外側の項目自体が書き込み可能なら、詳細オブジェクトをまるごと別のオブジェクトへ差し替えることは可能です。
  75. 6:30封印だけでデータ全体の構造を保証しようとすると複雑になるので、まずは項目の少ない平坦なデータから適用するのがおすすめです。
  76. 6:39逆に、内側の項目まで厳密に守らなくてよい設計なら、外側だけの封印で十分な場合もあります。
  77. 6:46似たメソッドとの違いを整理します。
  78. 6:49値の変更まで止めたい場合は、オブジェクト・フリーズが候補です。
  79. 6:54フリーズしたオブジェクトは、値の更新もできません。
  80. 6:58ただしフリーズも、入れ子へは自動で及びません。
  81. 7:01また、追加だけを禁止するプリベントエクステンションズは、既存項目の削除がまだできる点でシールより緩やかです。
  82. 7:10もう一つの注意はコピーです。
  83. 7:12展開構文で作り直した新しいオブジェクトには、封印の状態は引き継がれません。
  84. 7:18コピー側にも同じ制約が必要なら、新しいオブジェクトへ改めて適用してください。
  85. 7:24三つのメソッドの違いは、追加、削除、値の変更のうち、どこまで止めるかで整理すると覚えやすくなります。
  86. 7:32活用場面とまとめです。
  87. 7:34向いているのは、バッチ処理の総件数、完了件数、状態を保持する進捗情報や、
  88. 7:42読み込み中、成功件数、失敗件数をまとめた集計データなど、項目が先に決まっていて値だけが変わる小さなデータです。
  89. 7:50逆に、項目を自由に増減させる辞書のようなデータには向きません。
  90. 7:55導入のコツは、生成時に封印し、更新は検証を行う関数に任せることです。
  91. 8:01構造の事故と、業務上の不正な値を分けて防げます。
  92. 8:05まずは自分のコードで、守りたい項目の削除と、許可した更新を試してみてください。
  93. 8:12お疲れさまでした。
  94. 8:14オブジェクト・シールは、追加と削除を止めて、値の更新だけを残すメソッドだという一文で覚えておいてください。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Object.seal()でオブジェクトの項目を固定し、既存の値だけ更新する方法を解説。引数・戻り値、ブラウザーとNode.jsの実行手順、削除時の例外、入れ子への制約を学べます。

解説記事・サンプルコードを読む:JavaScriptのObject.seal():値を更新しながらオブジェクトの項目を固定する →