JavaScript オブジェクトプロパティ記述子
Object.defineProperty()
Object.defineProperty()
は、オブジェクトに新しいプロパティを定義したり、既存のプロパティの特性(記述子)を変更するために使用されます。プロパティ記述子には以下の属性を指定できます。
value
: プロパティの値(デフォルトはundefined
)。writable
: 値の変更を許可するかどうか(デフォルトはfalse
)。configurable
: プロパティの削除や記述子の変更を許可するかどうか(デフォルトはfalse
)。enumerable
: プロパティが列挙可能かどうか(デフォルトはfalse
)。get
: アクセサ関数を指定する(デフォルトはundefined
)。set
: セッター関数を指定する(デフォルトはundefined
)。
例: プロパティを定義
const obj = {};
Object.defineProperty(obj, 'property', {
value: 42,
writable: true,
configurable: true,
enumerable: true
});
console.log(obj.property); // 42
例: アクセサプロパティの定義
const obj = {};
let value = 0;
Object.defineProperty(obj, 'property', {
get() {
return value;
},
set(newValue) {
value = newValue * 2; // 倍にする
},
configurable: true,
enumerable: true
});
obj.property = 5;
console.log(obj.property); // 10
Object.defineProperties()
Object.defineProperties()
は複数のプロパティを一度に定義できる点で Object.defineProperty()
と異なります。
例: 複数プロパティの定義
const obj = {};
Object.defineProperties(obj, {
property1: {
value: 42,
writable: true
},
property2: {
get() {
return 'Hello';
},
configurable: true
}
});
console.log(obj.property1); // 42
console.log(obj.property2); // Hello
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()
は、指定したプロパティの記述子を取得します。記述子は以下の形式で返されます。
{
value: any,
writable: boolean,
enumerable: boolean,
configurable: boolean,
get: Function | undefined,
set: Function | undefined
}
例: プロパティ記述子の取得
const obj = {};
Object.defineProperty(obj, 'property', {
value: 42,
writable: false
});
const descriptor = Object.getOwnPropertyDescriptor(obj, 'property');
console.log(descriptor);
// { value: 42, writable: false, enumerable: false, configurable: false }
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors()
はオブジェクト内のすべてのプロパティの記述子を取得します。Object.assign()
と組み合わせて、オブジェクトの浅いコピーを作成するのによく使われます。
例: 記述子の一覧取得
const obj = {
property1: 42,
property2: 'Hello'
};
const descriptors = Object.getOwnPropertyDescriptors(obj);
console.log(descriptors);
/*
{
property1: { value: 42, writable: true, enumerable: true, configurable: true },
property2: { value: 'Hello', writable: true, enumerable: true, configurable: true }
}
*/
例: 浅いコピーの作成
const source = {
get property() {
return 'Getter value';
}
};
const copy = Object.defineProperties({}, Object.getOwnPropertyDescriptors(source));
console.log(copy.property); // Getter value
数学的な概念との対応
プロパティ記述子は数学的には「関数」や「マッピング」としてモデル化できます。たとえば、オブジェクトを集合 X
とし、プロパティ記述子をその集合上の射影として次のように表現できます:
f: X → Y
f(x) = 記述子
ここで、記述子は enumerable
, writable
, value
などのプロパティを含むベクトル空間と考えられます。
アクセサプロパティの場合、次のようにモデル化できます。
g: X → ℝ
h: ℝ → X
ここで g
は getter 関数、h
は setter 関数を表します。
実装例は、MathJax形式で次のように表されます:
$$ g(x) = x^2 $$
$$ h(y) = \sqrt{y} $$
このようにプロパティ記述子は数学的概念にも類似した構造を持っています。
まとめ
JavaScriptのオブジェクトプロパティ記述子は、オブジェクトのプロパティの動作を柔軟に制御する強力なツールです。Object.defineProperty
と Object.defineProperties
を使用することで、プロパティの動作を詳細に定義できます。また、Object.getOwnPropertyDescriptor
と Object.getOwnPropertyDescriptors
によってプロパティの記述子を確認でき、深い理解とデバッグに役立ちます。