Object.prototype.__proto__
非推奨: この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。
警告: オブジェクトの [[Prototype]]
を変更することは、現行の JavaScript エンジンがプロパティアクセスを最適化する性質上、どのブラウザーや JavaScript エンジンでも現在とても遅い処理となります。さらに、継承を変更することの効果は微妙で広範囲に及び、 obj.__proto__ = ...
文に費やされる時間に限らず、[[Prototype]]
が変更されたオブジェクトにアクセスするあらゆるコードに及ぶ可能性があります。詳しくは JavaScript engine fundamentals: optimizing prototypes で説明されています。
警告: __proto__
を使用することは議論の余地があり、推奨されません。その存在と正確な動作は、ウェブの互換性を確実に保持するための古い機能として標準化されただけであり、セキュリティ上のいくつかの課題と足かせを表示しています。対応をよりよくするためには、 Object.getPrototypeOf()
/Reflect.getPrototypeOf()
や Object.setPrototypeOf()
/Reflect.setPrototypeOf()
を推奨します。
__proto__
は Object
のアクセサープロパティ (ゲッター関数およびセッター関数) で、アクセスされるオブジェクトの内部の [[Prototype]]
(オブジェクトまたは null
のどちらか) を暴露します。
オブジェクトリテラル定義内で __proto__
プロパティを使用することで、オブジェクトの作成時にオブジェクト [[Prototype]]
を設定することができ、 Object.create()
の代わりになります。オブジェクト初期化子 / リテラルの構文を参照してください。この構文は標準であり、実装に最適化されており、 Object.prototype.__proto__
とは全く異なります。
構文
obj.__proto__
返値
ゲッターとして使用された場合、オブジェクトの [[Prototype]]
を返します。
例外
TypeError
-
拡張不可のオブジェクト、または不変プロトタイプエキゾチックオブジェクト、例えば
Object.prototype
やwindow
などのプロトタイプを設定しようとすると発生します。
解説
__proto__
ゲッター関数はオブジェクトの内部の [[Prototype]]
の値を外部に公開します。オブジェクトリテラルを使用して生成されたオブジェクトでは(プロトタイプセッター構文を使用しない限り)、この値は Object.prototype
です。配列リテラルを使用して作成したオブジェクトの場合、この値は Array.prototype
です。関数の場合、この値は Function.prototype
です。プロトタイプチェーンについては、継承とプロトタイプチェーンで詳しく説明しています。
__proto__
のセッターでオブジェクトの [[Prototype]]
を変更することができます。与えられた値はオブジェクト、または null
である必要があります。他の値が与えられた場合は何もしません。
Object.getPrototypeOf()
や Object.setPrototypeOf()
は Object
の静的プロパティとして常に利用でき、常に [[Prototype]]
の内部プロパティを反映しますが、 __proto__
プロパティはすべてのオブジェクトのプロパティとして常に存在するわけではなく、結果として [[Prototype]]
を確実に反映するわけではありません。
__proto__
プロパティは、ゲッター関数とセッター関数からなる Object.prototype
上の簡単なアクセサープロパティです。最終的にの Object.prototype
を参照する __proto__
に対してのプロパティアクセスはこのプロパティを探します。しかし、 Object.prototype
を参照しないアクセスはこのプロパティを探しません。 Object.prototype
が参照される前にいくつかの他の __proto__
プロパティが見つけられた場合、そのプロパティは、 Object.prototype
上で見つけられたプロパティを隠します。
null
プロトタイプオブジェクトは、 __proto__
アクセサープロパティを含め、 Object.prototype
からプロパティを継承しないため、このようなオブジェクトで __proto__
を読み込もうとすると、オブジェクトの実際の [[Prototype]]
に関係なく、値は常に undefined
となり、 __proto__
に代入すると、オブジェクトのプロトタイプを設定する代わりに、 __proto__
という新しいプロパティを作成することになります。さらに、 __proto__
は、セッターを発生させることなく、 Object.defineProperty()
によって、任意のオブジェクトインスタンス上の自分自身でプロパティとして再定義することができます。この場合、 __proto__
は [[Prototype]]
のアクセサーにできなくなりました。できれば、オブジェクトの [[Prototype]]
を設定したり取得したりするには、常に Object.getPrototypeOf()
と Object.setPrototypeOf()
を推奨します。
例
__proto__ の使用
function Circle() {}
const shape = {};
const circle = new Circle();
// オブジェクトプロトタイプの設定
// 非推奨。 参考用です。 実際のコードで使用しないでください。
shape.__proto__ = circle;
// オブジェクトプロトタイプの取得
console.log(shape.__proto__ === Circle); // false
const ShapeA = function () {};
const ShapeB = {
a() {
console.log("aaa");
},
};
ShapeA.prototype.__proto__ = ShapeB;
console.log(ShapeA.prototype.__proto__); // { a: [Function: a] }
const shapeA = new ShapeA();
shapeA.a(); // aaa
console.log(ShapeA.prototype === shapeA.__proto__); // true
const ShapeC = function () {};
const ShapeD = {
a() {
console.log("a");
},
};
const shapeC = new ShapeC();
shapeC.__proto__ = ShapeD;
shapeC.a(); // a
console.log(ShapeC.prototype === shapeC.__proto__); // false
function Test() {}
Test.prototype.myName = function () {
console.log("myName");
};
const test = new Test();
console.log(test.__proto__ === Test.prototype); // true
test.myName(); // myName
const obj = {};
obj.__proto__ = Test.prototype;
obj.myName(); // myName
仕様書
Specification |
---|
ECMAScript Language Specification # sec-object.prototype.__proto__ |
ブラウザーの互換性
BCD tables only load in the browser