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

警告: 最近の JavaScript エンジンがプロパティへのアクセスを最適化する方法の特質上、オブジェクトの [[Prototype]] を変更すると、すべてのブラウザーや 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__ プロパティがあります。

var dict = Object.setPrototypeOf({}, null);

ポリフィル

Object.setPrototypeOf が利用できない場合、より古い Object.prototype.__proto__ プロパティを使って、簡単に定義することができます。

// Only works in Chrome and FireFox, does not work in IE:
Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
  obj.__proto__ = proto;
  return obj; 
}

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

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

使い方

最初の例: チェーンをプロトタイプに追加する

function Mammal() {
  this.isMammal = 'yes';
}

function MammalSpecies(sMammalSpecies) {
  this.species = sMammalSpecies;
}

MammalSpecies.prototype = new Mammal();
MammalSpecies.prototype.constructor = MammalSpecies;

var oCat = new MammalSpecies('Felis');

console.log(oCat.isMammal); // 'yes'

function Animal() {
  this.breathing = 'yes';
}

Object.appendChain(oCat, new Animal());

console.log(oCat.breathing); // 'yes'

二番目の例: そのコンストラクタのインスタンスにプリミティブ値を変換し、プロトタイプにそのチェーンを追加する

function MySymbol() {
  this.isSymbol = 'yes';
}

var nPrime = 17;

console.log(typeof nPrime); // 'number'

var oPrime = Object.appendChain(nPrime, new MySymbol());

console.log(oPrime); // '17'
console.log(oPrime.isSymbol); // 'yes'
console.log(typeof oPrime); // 'object'

三番目の例: チェーンを Function.prototype オブジェクトに追加し、新しい関数をそのチェーンに追加する

function Person(sName) {
  this.identity = sName;
}

var george = Object.appendChain(new Person('George'),
                                'console.log("Hello guys!!");');

console.log(george.identity); // 'George'
george(); // 'Hello guys!!'

仕様書

仕様書 状態 備考
ECMAScript 2015 (6th Edition, ECMA-262)
Object.setPrototypeOf の定義
標準 初回定義
ECMAScript Latest Draft (ECMA-262)
Object.setPrototypeOf の定義
ドラフト  

ブラウザーの対応

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOS 版 SafariSamsung InternetNode.js
基本対応Chrome 完全対応 34Edge 完全対応 ありFirefox 完全対応 31IE 完全対応 11Opera 完全対応 ありSafari 完全対応 9WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 完全対応 ありFirefox Android 完全対応 31Opera Android 完全対応 ありSafari iOS 完全対応 ありSamsung Internet Android 完全対応 ありnodejs 完全対応 0.12

凡例

完全対応  
完全対応

関連情報

ドキュメントのタグと貢献者

このページの貢献者: mfuji09, woodmix, sii, shide55
最終更新者: mfuji09,