--- title: Object.prototype.__proto__ slug: Web/JavaScript/Reference/Global_Objects/Object/proto tags: - Deprecated - ECMAScript 2015 - JavaScript - Object - Property - Prototype - Reference translation_of: Web/JavaScript/Reference/Global_Objects/Object/proto ---
警告: オブジェクトの [[Prototype]]
を変更することは、最新の JavaScript エンジンがプロパティアクセスを最適化する仕組み上、すべてのブラウザーや JavaScript エンジンにおいて、とても低速な操作となります。プロトタイプの継承関係を変更することによる性能上の影響は微細で広範囲にわたり、単に obj.__proto__ = ...
という文の実行時間に留まらず、 [[Prototype]]
が変更されたいずれかのオブジェクトへのアクセスを持つあらゆるコードに及ぶ可能性があります。性能を気にしている場合、オブジェクトの [[Prototype]]
の変更は避けるべきです。代わりに、 {{JSxRef("Object.create()")}} を使用して意図する [[Prototype]]
をもつオブジェクトを新たに生成してください。
警告: Object.prototype.__proto__
は現時点でほとんどのブラウザーが対応していますが、そのプロパティの存在と正確な動作は、ウェブブラウザーの互換性を確保するためのレガシー機能として、 ECMAScript 2015 で初めて標準化されました。代わりに {{JSxRef("Object.getPrototypeOf()")}} を使用してください。
{{JSxRef("Object.prototype")}} の __proto__
プロパティは、アクセスされるオブジェクトの内部の [[Prototype]]
(オブジェクトまたは {{JSxRef("Global_Objects/null", "null")}} のどちらか) を暴露するアクセサプロパティ (ゲッター関数とセッター関数) です。
__proto__
の使用は、論争の的になり、推奨されていません。もともと ECMAScript 言語仕様には含まれていませんでしたが、現在のブラウザーでは結局それを実装しています。最近になって、 __proto__
プロパティはウェブブラウザー間の互換性を保つために ECMAScript2015 の仕様で標準化されたので、将来的には対応されることになります。これは非推奨扱いで、代わりに {{JSxRef("Object.getPrototypeOf")}}/{{JSxRef("Reflect.getPrototypeOf")}} および {{JSxRef("Object.setPrototypeOf")}}/{{JSxRef("Reflect.setPrototypeOf")}} を推奨しています (とはいえ、オブジェクトの [[Prototype]]
の設定は、性能が気になる場合には避けるべき低速の操作ですが)。
また、__proto__
プロパティは、生成時に [[Prototype]]
オブジェクトを設定するために {{JSxRef("Object.create()")}} の代わりとしてもオブジェクトリテラルの定義で使用されます。参照: オブジェクト初期化子
__proto__
ゲッター関数はオブジェクトの内部の [[Prototype]]
の値を外部に公開します。オブジェクトリテラルを使用して生成されたオブジェクトでは、この値は {{JSxRef("Object.prototype")}} です。配列リテラルを使用して生成されたオブジェクトでは、この値は {{JSxRef("Array.prototype")}} です。関数では、この値は {{JSxRef("Function.prototype")}} です。 new fun
を使用して生成されたオブジェクトでは、 fun
が JavaScript の ({{JSxRef("Array")}}、{{JSxRef("Boolean")}}、{{JSxRef("Date")}}、 {{JSxRef("Number")}}、 {{JSxRef("Object")}}、 {{JSxRef("String")}} などによって提供された内蔵コンストラクター関数のうちの一つである場合は — JavaScript の進化によって追加された新しいコンストラクタを含みます)、この値は常に fun.prototype
です。 new fun
を使用して生成されたオブジェクトでは、 fun
がスクリプトで定義された関数である場合、この値は常に fun.prototype
の値です。 (すなわち、コンストラクターがほかのオブジェクトを明示的に返さない場合、または fun.prototype
に再代入されていない場合)。
__proto__
のセッターでオブジェクトの [[Prototype]]
を変更することができます。オブジェクトは、 {{JSxRef("Object.isExtensible()")}} に応じて拡張可能である必要があります。拡張可能ではない場合、 {{JSxRef("Global_Objects/TypeError", "TypeError")}} が発生します。与えられた値はオブジェクト、または {{JSxRef("Global_Objects/null", "null")}} である必要があります。他の値が与えられた場合は何もしません。
プロトタイプが継承のためにどのように使用されるかを理解するには、ガイド記事の継承とプロトタイプチェーンを参照してください。
__proto__
プロパティは、ゲッター関数とセッター関数からなる {{JSxRef("Object.prototype")}} 上の簡単なアクセサープロパティです。最終的にの {{JSxRef("Object.prototype")}} を参照する __proto__
に対してのプロパティアクセスはこのプロパティを探します。しかし、 {{JSxRef("Object.prototype")}} を参照しないアクセスはこのプロパティを探しません。 {{JSxRef("Object.prototype")}} が参照される前にいくつかの他の __proto__
プロパティが見つけられた場合、そのプロパティは、 {{JSxRef("Object.prototype")}} 上で見つけられたプロパティを隠します。
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
仕様書 |
---|
{{SpecName('ESDraft', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}} |
{{Compat("javascript.builtins.Object.proto")}}