WEBVTT

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

2
00:00:00.882 --> 00:00:06.760
今回はジャバスクリプトのオブジェクト・プリベントエクステンションズを紹介します。

3
00:00:06.760 --> 00:00:12.344
これは、オブジェクトに新しいプロパティを追加することを禁止するメソッドです。

4
00:00:12.344 --> 00:00:16.165
ポイントは、禁止されるのが追加だけだということです。

5
00:00:16.165 --> 00:00:21.014
すでにある項目の値は変更できますし、項目を削除することもできます。

6
00:00:21.014 --> 00:00:28.215
必要な設定項目を先にそろえてからこのメソッドを呼ぶことで、設定名の書き間違いを早く見つけられます。

7
00:00:28.215 --> 00:00:32.256
この動画では、基本の使い方から、厳格モードとの関係、シールやフリーズとの違いまでを、

8
00:00:32.256 --> 00:00:36.298
実行結果と一緒に学びます。

9
00:00:36.298 --> 00:00:40.339
対応環境は広く、二千十五年以降の主要ブラウザーとノード・ジェイエスの両方で、

10
00:00:40.339 --> 00:00:44.380
追加のライブラリーなしに使えます。

11
00:00:44.380 --> 00:00:47.329
まず、なぜ追加を禁止したいのかを見ます。

12
00:00:47.329 --> 00:00:53.081
ジャバスクリプトのオブジェクトは、通常、後から自由にプロパティを追加できます。

13
00:00:53.081 --> 00:00:56.768
便利な反面、設定名を書き間違えると問題が起きます。

14
00:00:56.768 --> 00:01:00.897
例えば、本来はタイムアウトと書くべきところを、タイプミスで違うつづりにして代入しても、

15
00:01:00.897 --> 00:01:05.026
通常はエラーになりません。

16
00:01:05.026 --> 00:01:11.072
画面の例では、待ち時間は三千のまま変わらず、間違った名前の項目だけが増えています。

17
00:01:11.072 --> 00:01:17.266
設定が効いていないのにプログラムは動き続けるため、原因に気付きにくいバグになります。

18
00:01:17.266 --> 00:01:21.248
追加を禁止するのは、この書き間違いを表に出すためです。

19
00:01:21.248 --> 00:01:23.529
引数と戻り値のルールです。

20
00:01:23.529 --> 00:01:32.301
基本形は、オブジェクト・プリベントエクステンションズと書き、括弧の中に対象のオブジェクトを渡します。

21
00:01:32.301 --> 00:01:35.810
戻り値は、そのオブジェクトそのものです。

22
00:01:35.810 --> 00:01:40.898
コピーではないので、別の変数に入れても同じものを指します。

23
00:01:40.898 --> 00:01:52.302
画面の例では、戻り値と元の設定が同じかどうかがトゥルーになり、追加可能かどうかを調べるイズエクステンシブルはフォルスになりました。

24
00:01:52.302 --> 00:01:55.811
処理は同期で進み、プロミスは返りません。

25
00:01:55.811 --> 00:02:02.829
また、一度拡張不可能にしたオブジェクトを、拡張可能な状態へ戻す方法はありません。

26
00:02:02.829 --> 00:02:06.688
適用は元に戻せない操作として扱ってください。

27
00:02:06.688 --> 00:02:15.636
対象をほかの処理と共有している場合は、その処理からの追加も同じように禁止される点も覚えておきましょう。

28
00:02:15.636 --> 00:02:17.652
ここが重要なポイントです。

29
00:02:17.652 --> 00:02:25.250
拡張不可能なオブジェクトへ新しいプロパティを代入したときの動きは、厳格モードかどうかで変わります。

30
00:02:25.250 --> 00:02:30.522
厳格モードではタイプエラーが発生し、書き間違いにその場で気付けます。

31
00:02:30.522 --> 00:02:37.035
一方、非厳格モードでは、通常の代入による追加が黙って無視され、エラーにはなりません。

32
00:02:37.035 --> 00:02:45.098
画面の例では、関数の先頭にユーズ・ストリクトと書き、例外の名前がタイプエラーになることを確認しています。

33
00:02:45.098 --> 00:02:52.696
タイプミスの検出が目的なら、厳格モードを明示して、失敗を例外として受け取る書き方を選んでください。

34
00:02:52.696 --> 00:02:55.399
記事の中心となる実行例を読みます。

35
00:02:55.399 --> 00:02:59.931
待ち時間、再試行回数、ラベルという三つの設定を持つオブジェクトを用意し、

36
00:02:59.931 --> 00:03:04.463
プリベントエクステンションズを適用します。

37
00:03:04.463 --> 00:03:07.007
追加可能かどうかはフォルスです。

38
00:03:07.007 --> 00:03:11.619
既存の待ち時間を五千に更新すると、そのまま反映されました。

39
00:03:11.619 --> 00:03:17.820
次に、タイプミスの名前で代入するとタイプエラーになり、例外として受け取れます。

40
00:03:17.820 --> 00:03:22.272
例外を処理しているので、プログラムはそこで止まりません。

41
00:03:22.272 --> 00:03:29.587
このコードはノード・ジェイエスの実機でも、記事の期待出力と同じ結果になることを確認済みです。

42
00:03:29.587 --> 00:03:33.562
ブラウザーのコンソールでも、そのまま実行できます。

43
00:03:33.562 --> 00:03:42.308
なお、例外のメッセージ全文は実行環境ごとに異なるため、判定にはメッセージではなく例外の種類を使うのが安全です。

44
00:03:42.308 --> 00:03:45.927
追加が禁止されても、できることは残ります。

45
00:03:45.927 --> 00:03:54.372
画面の例では、プリベントエクステンションズを適用した後でも、既存の待ち時間を五千に更新できました。

46
00:03:54.372 --> 00:04:02.989
さらに、ラベルという項目をデリートで削除することもでき、残りは待ち時間と再試行回数だけになりました。

47
00:04:02.989 --> 00:04:09.883
つまり、このメソッドが固定するのは項目の顔ぶれであり、値そのものではありません。

48
00:04:09.883 --> 00:04:16.605
運用中に値を調整しながら使いたい設定に向いているのは、この緩やかさのためです。

49
00:04:16.605 --> 00:04:24.360
逆に言えば、値を守りたい場合や、削除まで止めたい場合には、このメソッドだけでは足りません。

50
00:04:24.360 --> 00:04:26.293
削除にまつわる注意点です。

51
00:04:26.293 --> 00:04:31.647
項目は削除できますが、削除した後に同じ名前で代入し直すことはできません。

52
00:04:31.647 --> 00:04:39.083
一度消えた名前への代入は、新しいプロパティの追加として扱われ、厳格モードではタイプエラーになります。

53
00:04:39.083 --> 00:04:43.247
画面の例でも、ラベルを削除した後の再追加が失敗しました。

54
00:04:43.247 --> 00:04:51.426
また、ディファインプロパティで新しい項目を定義しようとした場合も、厳格モードかどうかに関係なく例外になります。

55
00:04:51.426 --> 00:04:56.929
項目数を完全に固定したい要件では、この点を先に理解しておく必要があります。

56
00:04:56.929 --> 00:05:00.052
うっかり削除すると、元に戻せないからです。

57
00:05:00.052 --> 00:05:01.562
入れ子の注意点です。

58
00:05:01.562 --> 00:05:06.695
設定の中に別のオブジェクトがある場合、制限がかかるのは外側だけです。

59
00:05:06.695 --> 00:05:12.432
画面の例では、外側の設定にプリベントエクステンションズを適用していますが、

60
00:05:12.432 --> 00:05:18.169
内側のネットワークというオブジェクトには、再試行回数をそのまま追加できました。

61
00:05:18.169 --> 00:05:23.303
内側も守りたいなら、そのオブジェクトにも別途適用する必要があります。

62
00:05:23.303 --> 00:05:29.493
ただし、循環参照を含むデータへ無条件に再帰的に適用する設計は避けたほうが安全です。

63
00:05:29.493 --> 00:05:35.532
どの階層を制限するのかを先に決めて、必要な場所にだけ適用する方針にしてください。

64
00:05:35.532 --> 00:05:39.382
守る範囲を欲張らず、まずは外側の設定だけに絞るほうが、動作を確認しやすく、

65
00:05:39.382 --> 00:05:43.232
導入の失敗も少なくなります。

66
00:05:43.232 --> 00:05:45.519
このメソッドの限界も押さえます。

67
00:05:45.519 --> 00:05:50.379
プリベントエクステンションズが守るのは、項目の名前と顔ぶれだけです。

68
00:05:50.379 --> 00:05:58.383
既存の項目へ、負の数や文字列のような不適切な値を代入しても、書き込み可能なプロパティであれば止めてはくれません。

69
00:05:58.383 --> 00:06:02.670
画面の例でも、待ち時間に文字列がそのまま入ってしまいました。

70
00:06:02.670 --> 00:06:10.675
実務では、更新を受け付ける関数の中で、有限の数値かどうかや、許容範囲内かどうかを検証する処理を併用してください。

71
00:06:10.675 --> 00:06:17.964
また、これは自身のプロパティへの制約なので、継承元のプロトタイプの中身まで固定する機能でもありません。

72
00:06:17.964 --> 00:06:20.264
似たメソッドとの使い分けです。

73
00:06:20.264 --> 00:06:26.934
追加だけを禁止したいならプリベントエクステンションズ、追加に加えて削除も禁止したいならオブジェクト・シール、

74
00:06:26.934 --> 00:06:33.604
値の変更まで禁止したいならオブジェクト・フリーズが候補になります。

75
00:06:33.604 --> 00:06:38.050
シールもフリーズも、適用後は拡張不可能になる点は共通です。

76
00:06:38.050 --> 00:06:48.936
導入するときは、必要な項目をすべて作ってから適用すること、そして、後から項目を増やす処理へ同じオブジェクトを渡していないかを確認してください。

77
00:06:48.936 --> 00:06:55.683
まずは自分で管理する小さな設定オブジェクトから試すと、制約の影響を把握しやすくなります。

78
00:06:55.683 --> 00:07:00.129
どの方法を選んでも、入れ子の内側まで自動で守られるわけではない点は共通していますので、

79
00:07:00.129 --> 00:07:04.576
階層ごとの確認は欠かせません。

80
00:07:04.576 --> 00:07:05.573
まとめです。

81
00:07:05.573 --> 00:07:12.221
オブジェクト・プリベントエクステンションズは、オブジェクトへの新しいプロパティの追加を禁止するメソッドで、

82
00:07:12.221 --> 00:07:18.868
戻り値は対象そのもので、一度適用すると元に戻せません。

83
00:07:18.868 --> 00:07:24.851
既存の値の変更と項目の削除はできますが、削除した項目は再追加できません。

84
00:07:24.851 --> 00:07:30.169
入れ子の内側や、値の正しさまでは守らない点にも注意してください。

85
00:07:30.169 --> 00:07:39.143
タイプミスを例外として検出したいなら厳格モードを明示し、値の検証は別の処理で補うのが実務的な組み合わせです。

86
00:07:39.143 --> 00:07:43.630
設定の顔ぶれを守りたい場面で、ぜひ思い出してください。

87
00:07:43.630 --> 00:07:48.449
迷ったときは、追加だけを止めたいのか、削除や変更まで止めたいのかを先に言葉にしてから、

88
00:07:48.449 --> 00:07:53.268
使うメソッドを選んでください。

89
00:07:53.268 --> 00:07:54.764
お疲れさまでした。
