非推奨
この機能はウェブ標準から削除されました。まだ対応しているプラウザーがあるかもしれませんが、ゆくゆくはなくなるものです。使用を避け、できれば既存のコードを更新してください。このページの下部にあるブラウザーの対応を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。
警告: オブジェクトの [[Prototype]] を変更することは、最新の JavaScript エンジンがプロパティアクセスを最適化する仕組み上、すべてのブラウザーや JavaScript エンジンにおいて、とても低速な操作となります。プロトタイプの継承関係を変更することによる性能上の影響は微細で広範囲にわたり、単に obj.__proto__ = ... という文の実行時間に留まらず、 [[Prototype]] が変更されたいずれかのオブジェクトへのアクセスを持つあらゆるコードに及ぶ可能性があります。性能を気にしている場合、オブジェクトの [[Prototype]] の変更は避けるべきです。代わりに、 Object.create() を使用して意図する [[Prototype]] をもつオブジェクトを新たに生成してください。
警告: Object.prototype.__proto__ は現時点でほとんどのブラウザーが対応していますが、そのプロパティの存在と正確な動作は、ウェブブラウザーの互換性を確保するためのレガシー機能として、 ECMAScript 2015 で初めて標準化されました。代わりに Object.getPrototypeOf() を使用することが推奨されます。
Object.prototype の __proto__ プロパティは、アクセスされるオブジェクトの内部の [[Prototype]] (オブジェクトまたは null のどちらか) を暴露するアクセサプロパティ (ゲッター関数とセッター関数) です。
__proto__ の使用は、論争の的になり、推奨されていません。もともと EcmaScript 言語仕様には含まれていませんでしたが、現在のブラウザでは結局それを実装しています。最近になってようやく、 __proto__ プロパティはブラウザ間の互換性を保つために ECMAScript2015 の言語仕様で標準化されました。従って、将来的にサポートされることになります。ただしそれは非推奨で、 Object.getPrototypeOf/Reflect.getPrototypeOf 及び Object.setPrototypeOf/Reflect.setPrototypeOf を使用します (とはいえ、オブジェクトの [[Prototype]] の設定は、性能が気になる場合には避けるべき低速の操作ですが)。
また、__proto__ プロパティは、生成時に [[Prototype]] オブジェクトを設定するために Object.create() の代わりとしてもオブジェクトリテラルの定義で使用されます。参照: オブジェクト初期化子
構文
var Circle = function () {};
var shape = {};
var circle = new Circle();
// Set the object prototype.
// 非推奨。 参考用です。 実際のコードで使用しないでください。
shape.__proto__ = circle;
// オブジェクトのプロトタイプを取得します。
console.log(shape.__proto__ === circle); // true
var shape = function () {};
var p = {
a: function () {
console.log('aaa');
}
};
shape.prototype.__proto__ = p;
var circle = new shape();
circle.a(); // aaa
console.log(shape.prototype === circle.__proto__); // true
// or
var shape = function () {};
var p = {
a: function () {
console.log('a');
}
};
var circle = new shape();
circle.__proto__ = p;
circle.a(); // a
console.log(shape.prototype === circle.__proto__); // false
// or
function test() {};
test.prototype.myname = function () {
console.log('myname');
};
var a = new test();
console.log(a.__proto__ === test.prototype); // true
a.myname(); // myname
// or
var fn = function () {};
fn.prototype.myname = function () {
console.log('myname');
};
var obj = {
__proto__: fn.prototype
};
obj.myname(); // myname
注意: 最初に2つのアンダースコアがあり、5文字 "proto" が続いて、さらに2つのアンダースコアが続きます。
解説
__proto__ ゲッター関数はオブジェクトの内部の [[Prototype]] の値を外部にさらします。オブジェクトリテラルを使用して生成されたオブジェクトに対して、この値は Object.prototype です。配列リテラルを使用して生成されたオブジェクトに対して、この値は Array.prototype です。関数に対して、この値は Function.prototype です。 new fun を使用して生成されたオブジェクトの対して、この値は fun.prototype です。ここで、fun は JavaScript (Array、Boolean、Date、 Number、 Object、 Stringなど — JavaScript の進化として追加された新しいコンストラクタを含みます) によって提供されるビルトインコンストラクタ関数の一つです。new fun を使用して生成されたオブジェクトに対して、この値は常に fun.prototype の値です。ここで、fun はスクリプトで定義された関数です (すなわち、新しい値が fun.prototype に割り当てられている場合、以前生成された fun インスタンスも [[Prototype]] として新しい値を持ち、 __proto__ と fun.prototype として同じアドレスを参照します)。
__proto__ setter でオブジェクトの [[Prototype]] は変化することができます。オブジェクトは、 Object.isExtensible() に応じて拡張可能である必要があります。拡張可能ではない場合、 TypeError がスローされます。与えられた値はオブジェクト、または null である必要があります。他の値が与えられた場合は何もしません。
プロトタイプが継承のためにどのように使用されるかを理解するには、ガイド記事の継承とプロトチェーンを参照してください。
__proto__ プロパティは、 getter 関数と setter 関数からなる Object.prototype 上の簡単なアクセスプロパティです。最終的にの Object.prototype を参照する __proto__ に対してのプロパティアクセスはこのプロパティを探します。しかし、 Object.prototype を参照しないアクセスはこのプロパティを探しません。 Object.prototype が参照される前にいくつかの他の __proto__ プロパティが見つけられた場合、そのプロパティは、 Object.prototype 上で見つけられたプロパティを隠します。
仕様書
| 仕様書 | 状態 | 備考 |
|---|---|---|
| ECMAScript 2015 (6th Edition, ECMA-262) Object.prototype.__proto__ の定義 |
標準 | ECMAScript のウェブブラウザー向けの古い機能を追補するための (規程の) 付録に収録 (なお、この仕様書はすでに実装されているものを体系化するためのもの)。 |
| ECMAScript (ECMA-262) Object.prototype.__proto__ の定義 |
現行の標準 |
ブラウザーの互換性
| デスクトップ | モバイル | サーバー | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
__proto__ | Chrome 完全対応 1 | Edge 完全対応 12 | Firefox 完全対応 1 | IE 完全対応 11 | Opera 完全対応 10.5 | Safari 完全対応 3 | WebView Android 完全対応 1 | Chrome Android 完全対応 18 | Firefox Android 完全対応 4 | Opera Android 完全対応 11 | Safari iOS 完全対応 1 | Samsung Internet Android 完全対応 1.0 | nodejs 完全対応 あり |
凡例
- 完全対応
- 完全対応
- 非推奨。新しいウェブサイトでは使用しないでください。
- 非推奨。新しいウェブサイトでは使用しないでください。
互換性のメモ
ECMAScript 2015 仕様書では __proto__ はウェブブラウザー (ただし標準のもの) のみで対応が必要であるとしていますが、他の環境も旧式の利用のために同様に対応していることがあります。