このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

handler.getOwnPropertyDescriptor()

Baseline 広く利用可能

この機能は広く実装されており、多くのバージョンの端末やブラウザーで動作します。2016年9月以降、すべてのブラウザーで利用可能です。

handler.getOwnPropertyDescriptor() は、オブジェクトの [[GetOwnProperty]] 内部メソッドに対するトラップです。Object.getOwnPropertyDescriptor() などの操作で使用されます。

試してみましょう

const monster = {
  eyeCount: 4,
};

const handler = {
  getOwnPropertyDescriptor(target, prop) {
    console.log(`called: ${prop}`);
    // 予想される結果: "called: eyeCount"

    return { configurable: true, enumerable: true, value: 5 };
  },
};

const proxy = new Proxy(monster, handler);

console.log(Object.getOwnPropertyDescriptor(proxy, "eyeCount").value);
// 予想される結果: 5

構文

js
new Proxy(target, {
  getOwnPropertyDescriptor(target, property) {
  }
})

引数

次の引数は getOwnPropertyDescriptor() メソッドに渡されます。 this はハンドラーにバインドされます。

target

ターゲットオブジェクトです。

property

文字列または Symbol で、プロパティ名を表します。

返値

getOwnPropertyDescriptor() メソッドは、プロパティ記述子を表しますオブジェクトまたは undefined を返す必要があります。欠落している属性は、 Object.defineProperty() と同じ方法で正規化されます。

解説

介入

このトラップは下記の操作に介入できます。

他にも、[[GetOwnProperty]] 内部メソッドを呼び出すあらゆる操作に介入できます。

不変条件

プロキシーの [[GetOwnProperty]] 内部メソッドは、ハンドラー定義が次の不変条件のいずれかに違反する場合、 TypeError が発生します。

  • 結果は、Object または undefined のいずれかである必要があります。
  • プロパティが対象とするオブジェクトの構成不可な自分自身でプロパティとして存在する場合、そのプロパティを「存在しない」として報告することはできません。つまり、 Reflect.getOwnPropertyDescriptor()target のプロパティに対して configurable: false を返す場合、トラップは undefined を返してはなりません。
  • プロパティは、拡張不可なターゲットオブジェクトの自分自身で拡張可能なプロパティとして存在する場合、存在しないとして報告できません。つまり、ターゲットオブジェクトに対して Reflect.isExtensible()false を返す場合、トラップは undefined を返してはなりません。
  • プロパティは、対象とするオブジェクトの自分自身で固有のプロパティとして存在せず、かつ対象とするオブジェクトが拡張可能でない場合、存在すると報告できません。つまり、対象とするオブジェクトに対して Reflect.isExtensible()false を返し、対象とするオブジェクトの target にあるプロパティに対して Reflect.getOwnPropertyDescriptor()undefined を返す場合、トラップは undefined を返さなければなりません。
  • プロパティは、対象とするオブジェクトの構成不可プロパティとして存在する場合を除き、構成不可として報告できません。つまり、 Reflect.getOwnPropertyDescriptor()target のプロパティに対して undefined または configurable: true を返す場合、トラップは configurable: false を返してはなりません。
  • プロパティは、対象とするオブジェクトに構成不可かつ書き込み不可の自己プロパティとして存在する場合を除き、構成不可かつ書き込み不可の両方として報告できません。つまり、前回不変条件に加え、target のプロパティに対して Reflect.getOwnPropertyDescriptor()configurable: false, writable: true を返す場合、トラップは configurable: false, writable: false を返してはなりません。
  • 対象とするオブジェクトに該当するプロパティが存在する場合、その対象とするオブジェクトのプロパティの記述子は descriptor と互換性がある必要があります。つまり、target を通常のオブジェクトと見なした場合、 Object.defineProperty(target, property, resultObject) はエラーを発生させない必要があります。 Object.defineProperty() の参照するリファレンスには詳細な情報が含まれているが、要約すると、対象とするプロパティが構成不可である場合、次の条件が成立する必要があります。
    • configurableenumerablegetset は元の値と一致する必要があります。 writable は、前回の不変条件により元の値と一致する必要があります。
    • プロパティはデータまたはアクセサーのどちらかを変えることはできません。
    • 値属性は、writabletrueの場合にのみ変更可能です。

getOwnPropertyDescriptor のトラップ

次のコードでは Object.getOwnPropertyDescriptor() をトラップします。

js
const p = new Proxy(
  { a: 20 },
  {
    getOwnPropertyDescriptor(target, prop) {
      console.log(`called: ${prop}`);
      return { configurable: true, enumerable: true, value: 10 };
    },
  },
);

console.log(Object.getOwnPropertyDescriptor(p, "a").value);
// "called: a"
// 10

次のコードでは不変条件に違反します。

js
const obj = { a: 10 };
Object.preventExtensions(obj);
const p = new Proxy(obj, {
  getOwnPropertyDescriptor(target, prop) {
    return undefined;
  },
});

Object.getOwnPropertyDescriptor(p, "a"); // TypeError is thrown

仕様書

仕様書
ECMAScript® 2027 Language Specification
# sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p

ブラウザーの互換性

関連情報