Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Meta programming

TheProxy andReflect objects allow you to intercept and define custom behavior for fundamental language operations (e.g., property lookup, assignment, enumeration, function invocation, etc.). With the help of these two objects you are able to program at the meta level of JavaScript.

Proxies

Proxy objects allow you to intercept certain operations and to implement custom behaviors.

For example, getting a property on an object:

js
const handler = {  get(target, name) {    return name in target ? target[name] : 42;  },};const p = new Proxy({}, handler);p.a = 1;console.log(p.a, p.b); // 1, 42

TheProxy object defines atarget (an empty object here) and ahandler object, in which agettrap is implemented. Here, an object that is proxied will not returnundefined when getting undefined properties, but will instead return the number42.

Additional examples are available on theProxy reference page.

Terminology

The following terms are used when talking about the functionality of proxies.

handler

Placeholder object which contains traps.

traps

The methods that provide property access. (This is analogous to the concept oftraps in operating systems.)

target

Object which the proxy virtualizes. It is often used as storage backend for the proxy. Invariants (semantics that remain unchanged) regarding object non-extensibility or non-configurable properties are verified against the target.

invariants

Semantics that remain unchanged when implementing custom operations are calledinvariants. If you violate the invariants of a handler, aTypeError will be thrown.

Handlers and traps

The following table summarizes the available traps available toProxy objects. See thereference pages for detailed explanations and examples.

Handler / trapInterceptions
handler.getPrototypeOf()Object.getPrototypeOf()
Reflect.getPrototypeOf()
__proto__
Object.prototype.isPrototypeOf()
instanceof
handler.setPrototypeOf()Object.setPrototypeOf()
Reflect.setPrototypeOf()
handler.isExtensible()Object.isExtensible()
Reflect.isExtensible()
handler.preventExtensions()Object.preventExtensions()
Reflect.preventExtensions()
handler.getOwnPropertyDescriptor()Object.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor()
handler.defineProperty()Object.defineProperty()
Reflect.defineProperty()
handler.has()
Property query
foo in proxy
Inherited property query
foo in Object.create(proxy)
Reflect.has()
handler.get()
Property access
proxy[foo]
proxy.bar
Inherited property access
Object.create(proxy)[foo]
Reflect.get()
handler.set()
Property assignment
proxy[foo] = bar
proxy.foo = bar
Inherited property assignment
Object.create(proxy)[foo] = bar
Reflect.set()
handler.deleteProperty()
Property deletion
deleteproxy[foo]
deleteproxy.foo
Reflect.deleteProperty()
handler.ownKeys()Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
handler.apply()proxy(..args)
Function.prototype.apply() andFunction.prototype.call()
Reflect.apply()
handler.construct()new proxy(...args)
Reflect.construct()

RevocableProxy

TheProxy.revocable() method is used to create a revocableProxy object. This means that the proxy can be revoked via the functionrevoke and switches the proxy off.

Afterwards, any operation on the proxy leads to aTypeError.

js
const revocable = Proxy.revocable(  {},  {    get(target, name) {      return `[[${name}]]`;    },  },);const proxy = revocable.proxy;console.log(proxy.foo); // "[[foo]]"revocable.revoke();console.log(proxy.foo); // TypeError: Cannot perform 'get' on a proxy that has been revokedproxy.foo = 1; // TypeError: Cannot perform 'set' on a proxy that has been revokeddelete proxy.foo; // TypeError: Cannot perform 'deleteProperty' on a proxy that has been revokedconsole.log(typeof proxy); // "object", typeof doesn't trigger any trap

Reflection

Reflect is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of theproxy handler's.

Reflect is not a function object.

Reflect helps with forwarding default operations from the handler to thetarget.

WithReflect.has() for example, you get thein operator as a function:

js
Reflect.has(Object, "assign"); // true

A better apply() function

BeforeReflect, you typically use theFunction.prototype.apply() method to call a function with a giventhis value andarguments provided as an array (or anarray-like object).

js
Function.prototype.apply.call(Math.floor, undefined, [1.75]);

WithReflect.apply this becomes less verbose and easier to understand:

js
Reflect.apply(Math.floor, undefined, [1.75]);// 1Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);// "hello"Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;// 4Reflect.apply("".charAt, "ponies", [3]);// "i"

Checking if property definition has been successful

WithObject.defineProperty, which returns an object if successful, or throws aTypeError otherwise, you would use atry...catch block to catch any error that occurred while defining a property. BecauseReflect.defineProperty() returns a Boolean success status, you can just use anif...else block here:

js
if (Reflect.defineProperty(target, property, attributes)) {  // success} else {  // failure}

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp