Object.setPrototypeOf()

by 1 contributor:

This article is in need of an editorial review.

This translation is incomplete. Please help translate this article from English.

警告: オブジェクトの[[Prototype]]を変化させることは、最新のJavaScriptエンジンがプロパティアクセスを最適化する性質によって、すべてのブラウザやJavaScriptエンジンにおいて、とても低速な操作です。プロトタイプを変化させることの性能上の影響は、微細で広範囲にわたり、単にObject.setPrototypeOfに費やされる時間に制限はありません。しかし、[[Prototype]]が変化するすべてののオブジェクトへのアクセスを持つすべてのコードを拡張します。性能を気にしている場合、オブジェクトの[[Prototype]]を変化させることを避けるべきです。かわりに、Object.createを使用して望み通りの[[Prototype]]をもつオブジェクトを生成してください。

これは Harmony(ECMAScript 6) 提案の一部であり、実験段階の技術です。
この技術の仕様は安定していません。ブラウザ互換性の一覧表を確認してください。またこれらの構文や動作は、仕様変更などにより、新しいバージョンのブラウザでは変更される可能性があるという点に注意してください。

概要

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

構文

Object.setPrototypeOf(obj, prototype);

引数

obj
プロトタイプが設定されているオブジェクト。
prototype
オブジェクトの新しいプロトタイプ。(オブジェクトまたはnull).

説明

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

Object.setPrototypeOf()は、最新のECMAScript第6版標準ドラフトでサポートされています。一般的には、オブジェクトのプロトタイプを設定するための適切な方法と考えられています。もっと物議を醸すObject.prototype.__proto__ プロパティがあります。

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

ポリフィル

さらに古いObject.prototype.__proto__ プロパティを使用して、簡単にObject.setPrototypeOfを定義できます。既に利用可能ではありません。:

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 - Not enough arguments');
  }
  if (typeof oProto === 'number' || typeof oProto === 'boolean') {
    throw new TypeError('second argument to Object.appendChain must be an object or a 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');

alert(oCat.isMammal); // 'yes'

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

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

alert(oCat.breathing); // 'yes'

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

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

var nPrime = 17;

alert(typeof nPrime); // 'number'

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

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

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

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

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

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

仕様

仕様 状況 コメント
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Object.setProtoypeOf' in that specification.
Standard 初期定義。

ブラウザ実装状況

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari
基本サポート 34
See Issue 2675
31 (31)
See バグ 885788
11 (有) 未サポート
機能 Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本サポート 未サポート 未サポート 31.0 (31)
See バグ 885788
? 未サポート 未サポート

関連情報

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

Contributors to this page: shide55
最終更新者: shide55,