このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

handler.setPrototypeOf()

Baseline
広く利用可能

この機能は広く実装されており、多くのバージョンの端末やブラウザーで動作します。2016年9月以降、すべてのブラウザーで利用可能です。

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

試してみましょう

const handler = {
  setPrototypeOf(monster, monsterProto) {
    monster.geneticallyModified = true;
    return false;
  },
};

const monsterProto = {};
const monster = {
  geneticallyModified: false,
};

const proxy = new Proxy(monster, handler);
// Object.setPrototypeOf(proxy, monsterProto); // TypeError が発生

console.log(Reflect.setPrototypeOf(proxy, monsterProto));
// 予想される結果: false

console.log(monster.geneticallyModified);
// 予想される結果: true

構文

js
new Proxy(target, {
  setPrototypeOf(target, prototype) {
  }
})

引数

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

target

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

prototype

オブジェクトの新しいプロトタイプ、または null です。

返値

setPrototypeOf() メソッドは、プロトタイプが正常に変更されたかどうかを示す Boolean を返す必要があります。それ以外の値は論理値に変換されます

多くの操作(Object.setPrototypeOf() を含む)では、内部メソッド [[SetPrototypeOf]]false を返した場合、TypeError が発生します。

解説

介入

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

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

不変条件

プロキシーの [[SetPrototypeOf]] 内部メソッドでは、ハンドラー定義が次の不変条件のいずれかに違反する場合、TypeError を発生します。

  • 対象とするオブジェクトが拡張不可の場合は、プロトタイプを変更できません。つまり、Reflect.isExtensible()target に対して false を返す場合、かつ prototypeReflect.getPrototypeOf(target) の結果と一致しない場合、トラップは偽値を返す必要があります。

オブジェクトに新しいプロトタイプを設定することを禁止したい場合は、ハンドラーの setPrototypeOf() メソッドで false を返したり、例外を発生させたりするようにすることができます。

アプローチ 1: false を返す

このアプローチでは、例外を発生させる変更操作は、それ自身で例外を生成する必要があります。

例えば、 Object.setPrototypeOf() は、それ自体が TypeError を発生させます。 Reflect.setPrototypeOf() のように、失敗しても通常は例外が発生しない操作で変更操作が行われた場合、例外は発生しません。

js
const handlerReturnsFalse = {
  setPrototypeOf(target, newProto) {
    return false;
  },
};

const newProto = {},
  target = {};

const p1 = new Proxy(target, handlerReturnsFalse);
Object.setPrototypeOf(p1, newProto); // throws a TypeError
Reflect.setPrototypeOf(p1, newProto); // returns false

アプローチ 2: 例外を発生

後者のアプローチでは、変更を試みるすべての操作で例外が発生します。このアプローチは、例外を発生しない操作でも失敗時に例外を発生させたい場合や、カスタムの例外値を発生させたい場合に最適です。

js
const handlerThrows = {
  setPrototypeOf(target, newProto) {
    throw new Error("custom error");
  },
};

const newProto = {},
  target = {};

const p2 = new Proxy(target, handlerThrows);
Object.setPrototypeOf(p2, newProto); // throws new Error("custom error")
Reflect.setPrototypeOf(p2, newProto); // throws new Error("custom error")

仕様書

仕様書
ECMAScript® 2027 Language Specification
# sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v

ブラウザーの互換性

関連情報