handler.defineProperty()

handler.defineProperty()Object.defineProperty() に対するトラップです。

構文

const p = new Proxy(target, {
  defineProperty: function(target, property, descriptor) {
  }
});

引数

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

target
ターゲットオブジェクトです。
property
説明を受け取るプロパティの名前または Symbol です。
descriptor
定義や変更されるプロパティに対するディスクリプターです。

返値

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

解説

handler.defineProperty() メソッドは Object.defineProperty() に対するトラップです。

介入

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

不変条件

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

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

defineProperty のトラップ

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

const p = new Proxy({}, {
  defineProperty: function(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
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' }

仕様書

仕様書
ECMAScript (ECMA-262)
[[DefineOwnProperty]] の定義

ブラウザーの互換性

BCD tables only load in the browser

関連情報