handler.defineProperty()

The handler.defineProperty() method is a trap for the [[DefineOwnProperty]] object internal method, which is used by operations such as Object.defineProperty().

Try it

const handler = {
  defineProperty(target, key, descriptor) {
    invariant(key, "define");
    return true;
  },
};

function invariant(key, action) {
  if (key[0] === "_") {
    throw new Error(`Invalid attempt to ${action} private "${key}" property`);
  }
}

const monster = {};
const proxy = new Proxy(monster, handler);

console.log((proxy._secret = "easily scared"));
// Expected output: Error: Invalid attempt to define private "_secret" property

Syntax

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

Parameters

The following parameters are passed to the defineProperty() method. this is bound to the handler.

target

The target object.

property

A string or Symbol representing the property name.

descriptor

The descriptor for the property being defined or modified.

Return value

The defineProperty() method must return a Boolean indicating whether or not the property has been successfully defined. Other values are coerced to booleans.

Many operations, including Object.defineProperty() and Object.defineProperties(), throw a TypeError if the [[DefineOwnProperty]] internal method returns false.

Description

undefined

Interceptions

This trap can intercept these operations:

Or any other operation that invokes the [[DefineOwnProperty]] internal method.

Invariants

The proxy's [[DefineOwnProperty]] internal method throws a TypeError if the handler definition violates one of the following invariants:

Examples

undefined

Trapping of defineProperty

The following code traps 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"

When calling Object.defineProperty() or Reflect.defineProperty(), the descriptor passed to defineProperty() trap has one restriction—only following properties are usable (non-standard properties will be ignored):

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' }

Specifications

See also