VIDEO LESSON
JavaScriptのObject.preventExtensions():設定オブジェクトへの追加を禁止するの解説動画
再生時間 7:55動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00今回はジャバスクリプトのオブジェクト・プリベントエクステンションズを紹介します。
- 0:06これは、オブジェクトに新しいプロパティを追加することを禁止するメソッドです。
- 0:12ポイントは、禁止されるのが追加だけだということです。
- 0:16すでにある項目の値は変更できますし、項目を削除することもできます。
- 0:21必要な設定項目を先にそろえてからこのメソッドを呼ぶことで、設定名の書き間違いを早く見つけられます。
- 0:28この動画では、基本の使い方から、厳格モードとの関係、シールやフリーズとの違いまでを、
- 0:32実行結果と一緒に学びます。
- 0:36対応環境は広く、二千十五年以降の主要ブラウザーとノード・ジェイエスの両方で、
- 0:40追加のライブラリーなしに使えます。
- 0:44まず、なぜ追加を禁止したいのかを見ます。
- 0:47ジャバスクリプトのオブジェクトは、通常、後から自由にプロパティを追加できます。
- 0:53便利な反面、設定名を書き間違えると問題が起きます。
- 0:56例えば、本来はタイムアウトと書くべきところを、タイプミスで違うつづりにして代入しても、
- 1:00通常はエラーになりません。
- 1:05画面の例では、待ち時間は三千のまま変わらず、間違った名前の項目だけが増えています。
- 1:11設定が効いていないのにプログラムは動き続けるため、原因に気付きにくいバグになります。
- 1:17追加を禁止するのは、この書き間違いを表に出すためです。
- 1:21引数と戻り値のルールです。
- 1:23基本形は、オブジェクト・プリベントエクステンションズと書き、括弧の中に対象のオブジェクトを渡します。
- 1:32戻り値は、そのオブジェクトそのものです。
- 1:35コピーではないので、別の変数に入れても同じものを指します。
- 1:40画面の例では、戻り値と元の設定が同じかどうかがトゥルーになり、追加可能かどうかを調べるイズエクステンシブルはフォルスになりました。
- 1:52処理は同期で進み、プロミスは返りません。
- 1:55また、一度拡張不可能にしたオブジェクトを、拡張可能な状態へ戻す方法はありません。
- 2:02適用は元に戻せない操作として扱ってください。
- 2:06対象をほかの処理と共有している場合は、その処理からの追加も同じように禁止される点も覚えておきましょう。
- 2:15ここが重要なポイントです。
- 2:17拡張不可能なオブジェクトへ新しいプロパティを代入したときの動きは、厳格モードかどうかで変わります。
- 2:25厳格モードではタイプエラーが発生し、書き間違いにその場で気付けます。
- 2:30一方、非厳格モードでは、通常の代入による追加が黙って無視され、エラーにはなりません。
- 2:37画面の例では、関数の先頭にユーズ・ストリクトと書き、例外の名前がタイプエラーになることを確認しています。
- 2:45タイプミスの検出が目的なら、厳格モードを明示して、失敗を例外として受け取る書き方を選んでください。
- 2:52記事の中心となる実行例を読みます。
- 2:55待ち時間、再試行回数、ラベルという三つの設定を持つオブジェクトを用意し、
- 2:59プリベントエクステンションズを適用します。
- 3:04追加可能かどうかはフォルスです。
- 3:07既存の待ち時間を五千に更新すると、そのまま反映されました。
- 3:11次に、タイプミスの名前で代入するとタイプエラーになり、例外として受け取れます。
- 3:17例外を処理しているので、プログラムはそこで止まりません。
- 3:22このコードはノード・ジェイエスの実機でも、記事の期待出力と同じ結果になることを確認済みです。
- 3:29ブラウザーのコンソールでも、そのまま実行できます。
- 3:33なお、例外のメッセージ全文は実行環境ごとに異なるため、判定にはメッセージではなく例外の種類を使うのが安全です。
- 3:42追加が禁止されても、できることは残ります。
- 3:45画面の例では、プリベントエクステンションズを適用した後でも、既存の待ち時間を五千に更新できました。
- 3:54さらに、ラベルという項目をデリートで削除することもでき、残りは待ち時間と再試行回数だけになりました。
- 4:02つまり、このメソッドが固定するのは項目の顔ぶれであり、値そのものではありません。
- 4:09運用中に値を調整しながら使いたい設定に向いているのは、この緩やかさのためです。
- 4:16逆に言えば、値を守りたい場合や、削除まで止めたい場合には、このメソッドだけでは足りません。
- 4:24削除にまつわる注意点です。
- 4:26項目は削除できますが、削除した後に同じ名前で代入し直すことはできません。
- 4:31一度消えた名前への代入は、新しいプロパティの追加として扱われ、厳格モードではタイプエラーになります。
- 4:39画面の例でも、ラベルを削除した後の再追加が失敗しました。
- 4:43また、ディファインプロパティで新しい項目を定義しようとした場合も、厳格モードかどうかに関係なく例外になります。
- 4:51項目数を完全に固定したい要件では、この点を先に理解しておく必要があります。
- 4:56うっかり削除すると、元に戻せないからです。
- 5:00入れ子の注意点です。
- 5:01設定の中に別のオブジェクトがある場合、制限がかかるのは外側だけです。
- 5:06画面の例では、外側の設定にプリベントエクステンションズを適用していますが、
- 5:12内側のネットワークというオブジェクトには、再試行回数をそのまま追加できました。
- 5:18内側も守りたいなら、そのオブジェクトにも別途適用する必要があります。
- 5:23ただし、循環参照を含むデータへ無条件に再帰的に適用する設計は避けたほうが安全です。
- 5:29どの階層を制限するのかを先に決めて、必要な場所にだけ適用する方針にしてください。
- 5:35守る範囲を欲張らず、まずは外側の設定だけに絞るほうが、動作を確認しやすく、
- 5:39導入の失敗も少なくなります。
- 5:43このメソッドの限界も押さえます。
- 5:45プリベントエクステンションズが守るのは、項目の名前と顔ぶれだけです。
- 5:50既存の項目へ、負の数や文字列のような不適切な値を代入しても、書き込み可能なプロパティであれば止めてはくれません。
- 5:58画面の例でも、待ち時間に文字列がそのまま入ってしまいました。
- 6:02実務では、更新を受け付ける関数の中で、有限の数値かどうかや、許容範囲内かどうかを検証する処理を併用してください。
- 6:10また、これは自身のプロパティへの制約なので、継承元のプロトタイプの中身まで固定する機能でもありません。
- 6:17似たメソッドとの使い分けです。
- 6:20追加だけを禁止したいならプリベントエクステンションズ、追加に加えて削除も禁止したいならオブジェクト・シール、
- 6:26値の変更まで禁止したいならオブジェクト・フリーズが候補になります。
- 6:33シールもフリーズも、適用後は拡張不可能になる点は共通です。
- 6:38導入するときは、必要な項目をすべて作ってから適用すること、そして、後から項目を増やす処理へ同じオブジェクトを渡していないかを確認してください。
- 6:48まずは自分で管理する小さな設定オブジェクトから試すと、制約の影響を把握しやすくなります。
- 6:55どの方法を選んでも、入れ子の内側まで自動で守られるわけではない点は共通していますので、
- 7:00階層ごとの確認は欠かせません。
- 7:04まとめです。
- 7:05オブジェクト・プリベントエクステンションズは、オブジェクトへの新しいプロパティの追加を禁止するメソッドで、
- 7:12戻り値は対象そのもので、一度適用すると元に戻せません。
- 7:18既存の値の変更と項目の削除はできますが、削除した項目は再追加できません。
- 7:24入れ子の内側や、値の正しさまでは守らない点にも注意してください。
- 7:30タイプミスを例外として検出したいなら厳格モードを明示し、値の検証は別の処理で補うのが実務的な組み合わせです。
- 7:39設定の顔ぶれを守りたい場面で、ぜひ思い出してください。
- 7:43迷ったときは、追加だけを止めたいのか、削除や変更まで止めたいのかを先に言葉にしてから、
- 7:48使うメソッドを選んでください。
- 7:53お疲れさまでした。
この動画で学べること
Object.preventExtensions()で設定名のタイプミスによるプロパティ追加を防ぐ方法を解説。引数・戻り値、ブラウザーとNode.jsでの実行手順、既存値の変更や削除が可能な点を学びます。
解説記事・サンプルコードを読む:JavaScriptのObject.preventExtensions():設定オブジェクトへの追加を禁止する →