JavaScript

Object.setPrototypeOf()メソッド

 編集:2022.07.28 by T.A.

指定されたオブジェクトのプロトタイプ(つまり、内部の [[Prototype]] プロパティ)を、別のオブジェクトまたは null に設定します。

警告: オブジェクトの [[Prototype]] を変更すると、最近の JavaScript エンジンがプロパティへのアクセスを最適化する方法の特質上、すべてのブラウザーや JavaScript エンジンで、操作がとても低速になります。さらに、プロトタイプを変更することの性能への影響は細かく広範囲にわたり、Object.setPrototypeOf(...) 文に費やされる時間だけではなく、[[Prototype]] が変更されたすべてのオブジェクトへのアクセスを持つすべてのコードに影響する可能性があります。

この機能は言語の一部であるため、その機能の実装による負荷は(理念上は)エンジンの開発者によります。エンジンの開発者がこの問題に対処するまでの間、性能が気になる場合は、オブジェクトの [[Prototype]] を変更することは避けるべきです。代わりに、Object.create() を使用して必要な [[Prototype]] をもつオブジェクトを生成してください。

Object.setPrototypeOf(obj, prototype)
obj プロトタイプとして設定されるオブジェクト。
prototype オブジェクトの新しいプロトタイプ(オブジェクトまたは null)。
戻り値

指定されたオブジェクト。

解説

[[Prototype]] が変更されるオブジェクトが Object.isExtensible() に応じて拡張不可の場合、TypeError 例外を投げます。prototype 引数がオブジェクトまたは null ではない場合(つまり、数値、文字列、boolean、undefined のいずれか)、何もしません。さもなければ、このメソッドは obj の [[Prototype]] を新しい値に変更します。

Object.setPrototypeOf() は、ECMAScript 2015 仕様書にあります。一般的には、オブジェクトのプロトタイプを設定するための適切な方法と考えられています。もっと物議を醸す Object.prototype.__proto__ プロパティがあります。

プロトタイプチェーンの追加

Object.getPrototypeOf() と Object.prototype.__proto__ の組み合わせによってプロトタイプ チェーン全体を新しいプロトタイプ オブジェクトに追加できます。

/**
*** Object.appendChain(@object, @prototype)
*
* Appends the first non-native prototype of a chain to a new prototype.
* Returns @object (if it was a primitive value it will transformed into an object).
*
*** Object.appendChain(@object [, "@arg_name_1", "@arg_name_2", "@arg_name_3", "..."], "@function_body")
*** Object.appendChain(@object [, "@arg_name_1, @arg_name_2, @arg_name_3, ..."], "@function_body")
*
* Appends the first non-native prototype of a chain to the native Function.prototype object, then appends a
* new Function(["@arg"(s)], "@function_body") to that chain.
* Returns the function.
*
**/

Object.appendChain = function(oChain, oProto) {
  if (arguments.length < 2) {
    throw new TypeError('Object.appendChain - 引数が足りません');
  }
  if (typeof oProto !== 'object' && typeof oProto !== 'string') {
    throw new TypeError('Object.appendChain の第二引数は object か string でなければなりません');
  }

  var oNewProto = oProto,
      oReturn = o2nd = oLast = oChain instanceof this ? oChain : new oChain.constructor(oChain);

  for (var o1st = this.getPrototypeOf(o2nd);
    o1st !== Object.prototype && o1st !== Function.prototype;
    o1st = this.getPrototypeOf(o2nd)
  ) {
    o2nd = o1st;
  }

  if (oProto.constructor === String) {
    oNewProto = Function.prototype;
    oReturn = Function.apply(null, Array.prototype.slice.call(arguments, 1));
    this.setPrototypeOf(oReturn, oLast);
  }

  this.setPrototypeOf(o2nd, oNewProto);
  return oReturn;
}
使い方

¶省く

Object.setPrototypeOf の使用
var dict = Object.setPrototypeOf({}, null);
ポリフィル

¶省く


テスト