JavaScript オブジェクトプロパティ記述子

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.definePropertyObject.defineProperties を使用することで、プロパティの動作を詳細に定義できます。また、Object.getOwnPropertyDescriptorObject.getOwnPropertyDescriptors によってプロパティの記述子を確認でき、深い理解とデバッグに役立ちます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です