WEBVTT

1
00:00:00.000 --> 00:00:01.030
こんにちは。

2
00:00:01.030 --> 00:00:06.009
今回はジャバスクリプトのオブジェクト・シールを紹介します。

3
00:00:06.009 --> 00:00:10.816
これは、オブジェクトの項目の構成を固定するメソッドです。

4
00:00:10.816 --> 00:00:18.886
たとえば、処理の進み具合を表すデータでは、総件数や完了件数、状態といった項目が決まっています。

5
00:00:18.886 --> 00:00:26.268
値は途中で変わりますが、必要な項目が途中で消えてしまうと、集計結果がおかしくなります。

6
00:00:26.268 --> 00:00:32.620
シールを使えば、項目の追加と削除を止めたまま、既存の値だけを更新できます。

7
00:00:32.620 --> 00:00:38.973
項目が決まっている共有データで、事故を防ぐための仕組みだと考えてください。

8
00:00:38.973 --> 00:00:46.012
この先では、できる操作とできない操作を、実行結果と一緒に一つずつ確かめていきます。

9
00:00:46.012 --> 00:00:47.376
まず動作環境です。

10
00:00:47.376 --> 00:00:54.044
オブジェクト・シールはブラウザー専用の機能ではなく、ジャバスクリプトの標準の仕組みです。

11
00:00:54.044 --> 00:00:59.197
二千十五年七月以降、主要ブラウザーを横断して利用できる機能とされており、

12
00:00:59.197 --> 00:01:04.350
現在のクローム、エッジ、ファイアフォックス、サファリで使えます。

13
00:01:04.350 --> 00:01:09.200
ノード・ジェイエスでも動作し、追加のパッケージは必要ありません。

14
00:01:09.200 --> 00:01:14.201
記事の実行環境は現行ブラウザーとノード・ジェイエス二十二以降です。

15
00:01:14.201 --> 00:01:20.717
古い環境へ入れる場合は、タイプオブで関数として存在するかを確認してから使ってください。

16
00:01:20.717 --> 00:01:27.992
外部ライブラリも、画面操作も、通信も使わないサンプルなので、どちらの環境でも同じ手順で試せます。

17
00:01:27.992 --> 00:01:30.326
基本の書き方を見ましょう。

18
00:01:30.326 --> 00:01:36.251
オブジェクト・シールに、固定したいオブジェクトを一つ渡すだけです。

19
00:01:36.251 --> 00:01:40.560
戻り値は、引数に渡したのと同じオブジェクトです。

20
00:01:40.560 --> 00:01:44.331
新しいコピーが作られるわけではありません。

21
00:01:44.331 --> 00:01:50.345
封印すると、そのオブジェクト自身のプロパティはすべて、コンフィギュラブルがフォルスになり、

22
00:01:50.345 --> 00:01:56.360
追加も削除も、属性の変更もできなくなります。

23
00:01:56.360 --> 00:02:02.285
一方で、書き込み可能な既存プロパティの値は、そのまま更新できます。

24
00:02:02.285 --> 00:02:05.158
つまり、形は固定、値は可変です。

25
00:02:05.158 --> 00:02:10.005
この二つの顔を押さえることが、理解の出発点になります。

26
00:02:10.005 --> 00:02:18.444
封印できたかどうかは、オブジェクト・イズシールドに渡すと、トゥルーかフォルスかで確認できます。

27
00:02:18.444 --> 00:02:21.024
封印する前に大切な準備があります。

28
00:02:21.024 --> 00:02:27.095
後から項目を追加できないので、必要な項目はすべて先に用意しておく必要があります。

29
00:02:27.095 --> 00:02:34.076
たとえば完了時刻のように、後で値が決まる項目も、最初はヌルを入れて場所だけ確保しておきます。

30
00:02:34.076 --> 00:02:36.959
また、封印は値の正しさを保証しません。

31
00:02:36.959 --> 00:02:42.726
件数を入れる場所に文字列を代入しても、書き込み可能なら更新できてしまいます。

32
00:02:42.726 --> 00:02:47.734
数値の範囲や状態名のチェックは、更新用の関数で別に行ってください。

33
00:02:47.734 --> 00:02:54.564
さらに、同じオブジェクトを別の変数から参照している場合、その変数にも封印の影響が及びます。

34
00:02:54.564 --> 00:03:02.152
封印は、オブジェクトを作るタイミングで一度だけ行う設計にすると、運用のルールが分かりやすくなります。

35
00:03:02.152 --> 00:03:03.524
ここから実例です。

36
00:03:03.524 --> 00:03:06.572
進捗情報を表すオブジェクトを用意します。

37
00:03:06.572 --> 00:03:14.040
中身は、総件数が三、完了件数がゼロ、状態がウェーティング、そして担当者を持つ詳細オブジェクトです。

38
00:03:14.040 --> 00:03:20.136
このオブジェクトにオブジェクト・シールを適用し、戻り値を別の変数で受け取ります。

39
00:03:20.136 --> 00:03:25.622
実行すると、戻り値と元のオブジェクトが同一かどうかはトゥルーになります。

40
00:03:25.622 --> 00:03:32.633
つまり封印は、コピーを作る処理ではなく、渡したオブジェクトそのもののルールを変える処理です。

41
00:03:32.633 --> 00:03:39.949
ブラウザーのコンソールでも、ノード・ジェイエスのファイル実行でも、同じコードがそのまま動きます。

42
00:03:39.949 --> 00:03:45.740
ここで使う進捗データは、この後の削除や追加の実験でも、そのまま使い続けます。

43
00:03:45.740 --> 00:03:48.939
次に、できる操作とできない操作を比べます。

44
00:03:48.939 --> 00:03:54.119
まず、完了件数を一に、状態をランニングに書き換える更新は成功します。

45
00:03:54.119 --> 00:03:59.603
次に、完了件数をデリートで削除しようとすると、タイプエラーが発生します。

46
00:03:59.603 --> 00:04:06.001
さらに、開始日時という新しい項目を追加しようとしても、やはりタイプエラーになります。

47
00:04:06.001 --> 00:04:13.466
サンプルでは、関数の中でストリクトモードを有効にし、エラーをキャッチして名前だけを表示しています。

48
00:04:13.466 --> 00:04:17.579
失敗しても処理を止めずに、残りの確認へ進める構成です。

49
00:04:17.579 --> 00:04:22.911
削除されなかったことと、追加されなかったことは、次の出力で確かめます。

50
00:04:22.911 --> 00:04:30.528
なお、代入による追加が通常モードでは例外にならない場合がある点は、後のセクションで改めて説明します。

51
00:04:30.528 --> 00:04:32.868
期待出力を順に確認しましょう。

52
00:04:32.868 --> 00:04:37.081
最初に、同一オブジェクトであることがトゥルーと出ます。

53
00:04:37.081 --> 00:04:43.789
次に進捗は一スラッシュ三、状態はランニングと表示され、更新が成功したことが分かります。

54
00:04:43.789 --> 00:04:47.377
続いて、削除と追加はどちらもタイプエラーです。

55
00:04:47.377 --> 00:04:52.682
その後も完了件数は一のまま残り、追加しようとした項目は存在しません。

56
00:04:52.682 --> 00:04:58.610
最後に、詳細オブジェクトへのノート追加は成功し、チェック済みと表示されます。

57
00:04:58.610 --> 00:05:02.355
この最後の一行が、入れ子の注意点につながります。

58
00:05:02.355 --> 00:05:08.751
エラーメッセージの全文は環境で異なるため、コードでは例外の名前だけを比べています。

59
00:05:08.751 --> 00:05:13.510
ブラウザーで実行すると、コンソールにアンディファインドが追加で表示されることがありますが、

60
00:05:13.510 --> 00:05:18.268
これはログとは別の評価結果です。

61
00:05:18.268 --> 00:05:20.725
失敗を見落とさないための注意です。

62
00:05:20.725 --> 00:05:27.661
通常モードでは、封印済みオブジェクトへの追加などが、例外を出さずに静かに失敗することがあります。

63
00:05:27.661 --> 00:05:32.140
処理が止まらないので、追加できたと思い込む事故につながります。

64
00:05:32.140 --> 00:05:38.932
サンプルがストリクトモードを明記しているのは、この失敗を例外として目に見える形にするためです。

65
00:05:38.932 --> 00:05:43.484
ジャバスクリプトのモジュールは自動的にストリクトモードになりますが、環境による差を避けるため、

66
00:05:43.484 --> 00:05:48.035
例では関数の中に明記しています。

67
00:05:48.035 --> 00:05:53.093
実務では、想定外の例外まで握りつぶさず、原因を追える形にしてください。

68
00:05:53.093 --> 00:05:56.994
例外の種類を確認してから処理を続けるのか、そのまま呼び出し元へ伝えるのかは、

69
00:05:56.994 --> 00:06:00.896
事前に決めておくとよいでしょう。

70
00:06:00.896 --> 00:06:05.047
入れ子、つまりネストしたオブジェクトの扱いも重要です。

71
00:06:05.047 --> 00:06:09.968
外側を封印しても、内側のオブジェクトに封印は自動で広がりません。

72
00:06:09.968 --> 00:06:15.196
サンプルでも、詳細オブジェクトへ新しい項目を追加できてしまいました。

73
00:06:15.196 --> 00:06:21.961
内側も固定したい場合は、内側に対して個別にオブジェクト・シールを適用する必要があります。

74
00:06:21.961 --> 00:06:30.571
ただし、外側の項目自体が書き込み可能なら、詳細オブジェクトをまるごと別のオブジェクトへ差し替えることは可能です。

75
00:06:30.571 --> 00:06:39.951
封印だけでデータ全体の構造を保証しようとすると複雑になるので、まずは項目の少ない平坦なデータから適用するのがおすすめです。

76
00:06:39.951 --> 00:06:46.716
逆に、内側の項目まで厳密に守らなくてよい設計なら、外側だけの封印で十分な場合もあります。

77
00:06:46.716 --> 00:06:49.394
似たメソッドとの違いを整理します。

78
00:06:49.394 --> 00:06:54.278
値の変更まで止めたい場合は、オブジェクト・フリーズが候補です。

79
00:06:54.278 --> 00:06:58.217
フリーズしたオブジェクトは、値の更新もできません。

80
00:06:58.217 --> 00:07:01.841
ただしフリーズも、入れ子へは自動で及びません。

81
00:07:01.841 --> 00:07:10.349
また、追加だけを禁止するプリベントエクステンションズは、既存項目の削除がまだできる点でシールより緩やかです。

82
00:07:10.349 --> 00:07:12.554
もう一つの注意はコピーです。

83
00:07:12.554 --> 00:07:18.384
展開構文で作り直した新しいオブジェクトには、封印の状態は引き継がれません。

84
00:07:18.384 --> 00:07:24.370
コピー側にも同じ制約が必要なら、新しいオブジェクトへ改めて適用してください。

85
00:07:24.370 --> 00:07:32.248
三つのメソッドの違いは、追加、削除、値の変更のうち、どこまで止めるかで整理すると覚えやすくなります。

86
00:07:32.248 --> 00:07:34.185
活用場面とまとめです。

87
00:07:34.185 --> 00:07:42.196
向いているのは、バッチ処理の総件数、完了件数、状態を保持する進捗情報や、

88
00:07:42.196 --> 00:07:50.207
読み込み中、成功件数、失敗件数をまとめた集計データなど、項目が先に決まっていて値だけが変わる小さなデータです。

89
00:07:50.207 --> 00:07:55.665
逆に、項目を自由に増減させる辞書のようなデータには向きません。

90
00:07:55.665 --> 00:08:01.651
導入のコツは、生成時に封印し、更新は検証を行う関数に任せることです。

91
00:08:01.651 --> 00:08:05.877
構造の事故と、業務上の不正な値を分けて防げます。

92
00:08:05.877 --> 00:08:12.744
まずは自分のコードで、守りたい項目の削除と、許可した更新を試してみてください。

93
00:08:12.744 --> 00:08:14.328
お疲れさまでした。

94
00:08:14.328 --> 00:08:23.660
オブジェクト・シールは、追加と削除を止めて、値の更新だけを残すメソッドだという一文で覚えておいてください。
