handler.defineProperty()

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

試してみましょう

構文

js
new Proxy(target, {
  defineProperty(target, property, descriptor) {
  }
});

引数

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

target

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

property

説明を受け取るプロパティの名前または Symbol です。

descriptor

定義や変更されるプロパティに対するディスクリプターです。

返値

defineProperty() メソッドはプロパティが正しく定義されたかどうかを表す論理値を返す必要があります。

解説

介入

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

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

不変条件

以下の不変条件に違反している場合、プロキシーは TypeError を発生します。

  • ターゲットオブジェクトが拡張不可の場合、プロパティは追加できません。
  • ターゲットオブジェクトの構成不可の独自のプロパティとして存在しない場合、プロパティは構成不可とみなされ、追加や変更ができません。
  • ターゲットオブジェクトの対応する構成可能なプロパティが存在する場合、プロパティは構成不可にすることができません。
  • 対応するターゲットオブジェクトのプロパティが存在する場合、Object.defineProperty(target, prop, descriptor) は例外をスローしません。
  • strict モードでは、defineProperty ハンドラーから false が返ってきた場合、TypeError 例外をスローします。

defineProperty のトラップ

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

js
const p = new Proxy(
  {},
  {
    defineProperty(target, prop, descriptor) {
      console.log(`called: ${prop}`);
      return true;
    },
  },
);

const desc = { configurable: true, enumerable: true, value: 10 };
Object.defineProperty(p, "a", desc); // "called: a"

Object.defineProperty() または Reflect.defineProperty() を呼び出した時、 defineProperty() トラップに渡されるディスクリプターには制約があります。下記のプロパティのみが使用可能で、標準ではないプロパティは無視されます。

  • enumerable
  • configurable
  • writable
  • value
  • get
  • set
js
const p = new Proxy(
  {},
  {
    defineProperty(target, prop, descriptor) {
      console.log(descriptor);
      return Reflect.defineProperty(target, prop, descriptor);
    },
  },
);

Object.defineProperty(p, "name", {
  value: "proxy",
  type: "custom",
}); // { value: 'proxy' }

仕様書

Specification
ECMAScript Language Specification
# sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc

ブラウザーの互換性

BCD tables only load in the browser

関連情報