handler.getPrototypeOf()

handler.getPrototypeOf() メソッドは [[GetPrototypeOf]] 内部メソッドに対するトラップです。

試してみましょう

構文

const p = new Proxy(obj, {
  getPrototypeOf(target) {
  ...
  }
});

引数

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

target

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

返値

getPrototypeOf() メソッドはオブジェクト、または null を返さなければなりません。

解説

介入

不変条件

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

  • getPrototypeOf メソッドはオブジェクト、または null を返さなければなりません。
  • targetが拡張不可の場合、 Object.getPrototypeOf(proxy) メソッドは Object.getPrototypeOf(target) と同じ値を返さなければなりません。

基本的な使い方

const obj = {};
const proto = {};
const handler = {
    getPrototypeOf(target) {
        console.log(target === obj);   // true
        console.log(this === handler); // true
        return proto;
    }
};

const p = new Proxy(obj, handler);
console.log(Object.getPrototypeOf(p) === proto);    // true

getPrototypeOf トラップが発生する5つの方法

const obj = {};
const p = new Proxy(obj, {
    getPrototypeOf(target) {
        return Array.prototype;
    }
});
console.log(
    Object.getPrototypeOf(p) === Array.prototype,  // true
    Reflect.getPrototypeOf(p) === Array.prototype, // true
    p.__proto__ === Array.prototype,               // true
    Array.prototype.isPrototypeOf(p),              // true
    p instanceof Array                             // true
);

2種類の例外

const obj = {};
const p = new Proxy(obj, {
    getPrototypeOf(target) {
        return 'foo';
    }
});
Object.getPrototypeOf(p); // TypeError: "foo" is not an object or null

const obj = Object.preventExtensions({});
const p = new Proxy(obj, {
    getPrototypeOf(target) {
        return {};
    }
});
Object.getPrototypeOf(p); // TypeError: expected same prototype value

仕様書

Specification
ECMAScript Language Specification
# sec-proxy-object-internal-methods-and-internal-slots-getprototypeof

ブラウザーの互換性

BCD tables only load in the browser

関連情報