Object.defineProperty()
の使いどころについて調べた
JavaScriptのObject.defineProperty()
は、オブジェクトのプロパティを詳細に定義・制御するためのメソッド
通常、オブジェクトにプロパティを追加すると、そのプロパティは自由に変更・削除できるが、Object.defineProperty()
を使うとそれらの動作を制限できる
プロパティ記述子とは
Object.defineProperty()
の第3引数には「プロパティ記述子」と呼ばれるオブジェクトを指定する
プロパティ記述子には以下のような属性がある
- value: プロパティの値
- writable: 値の変更を許可するか(
true
orfalse
) - enumerable:
for...in
やObject.keys()
で列挙されるか - configurable: 削除や再定義が可能か
- get: プロパティ取得時に実行する関数(ゲッター)
- set: プロパティ設定時に実行する関数(セッター)
Object.defineProperty()
の基本的な使い方
オブジェクトにプロパティを追加し、値の変更を禁止する例
const obj = {}; Object.defineProperty(obj, 'property1', { value: 42, writable: false, // 変更不可 enumerable: true, // 列挙可能 configurable: true // 削除や再定義が可能 }); console.log(obj.property1); // 42 obj.property1 = 100; console.log(obj.property1); // 42(writableがfalseなので変更されない)
ゲッター・セッターを使った例
get
とset
を使って、プロパティの値を取得・設定する際の動作を制御できる
const obj = {}; let internalValue = 0; Object.defineProperty(obj, 'property2', { get() { return internalValue; }, set(value) { internalValue = value * 2; // 設定した値の2倍にする }, enumerable: true, configurable: true }); obj.property2 = 10; console.log(obj.property2); // 20
Object.defineProperty()
の使いどころ
プロパティの値を変更不可にする
データの不変性を保証し、意図しない変更を防ぐ
プロパティの列挙を制御する
一部のプロパティだけをfor...in
やObject.keys()
で列挙可能にする
ゲッター・セッターを使ってデータの整合性を保つ
特定の処理を挟むことで、データの変更を制御
他の活用例
変更を監視するオブジェクトを作る
Object.defineProperty()
を活用すると、変更を監視するオブジェクトを作ることもできる
例えば、プロパティの変更時に特定の処理を実行するようにすれば、簡易的なデータバインディングが可能
const obj = {}; Object.defineProperty(obj, 'watchedProperty', { set(value) { console.log(`値が ${value} に変更されました`); } }); obj.watchedProperty = 10; // "値が 10 に変更されました" と表示
Object.defineProperty()
のvalue
にclass
を指定する
Object.defineProperty()
のvalue
にclass
を指定することも可能
JavaScriptのclass
は関数(class
構文で定義されたコンストラクタ関数)であり、オブジェクトとして扱えるため、value
にclass
を指定するとそのクラスをプロパティとして保持できる
実際の例
class MyClass { constructor(name) { this.name = name; } greet() { return `Hello, ${this.name}!`; } } const obj = {}; Object.defineProperty(obj, 'MyClassProperty', { value: MyClass, // クラスをプロパティとして設定 writable: false, enumerable: true, configurable: true }); console.log(obj.MyClassProperty); // [class MyClass] const instance = new obj.MyClassProperty('Alice'); console.log(instance.greet()); // "Hello, Alice!"
ポイント
value
にclass
を指定すると、そのクラス自体をオブジェクトのプロパティとして保持できるobj.MyClassProperty
にはMyClass
というクラスが格納されるnew obj.MyClassProperty()
を使うことで、そのクラスのインスタンスを作成できる
制限事項
value
にクラスを指定した場合、writable: false
にすると、後からそのプロパティを別の値に変更できなくなる- クラスのインスタンスではなく、クラスそのもの をプロパティに格納している点に注意
- クラスをプロパティに持つことは可能だが、通常は
import/export
やrequire()
を使ってモジュールとして管理するほうが一般的