MDN wants to talk to developers like you: https://qsurvey.mozilla.com/s3/8d22564490d8

Object.prototype.__proto__

この翻訳は不完全です。英語から この記事を翻訳 してください。

警告: オブジェクトの[[Prototype]]を変更することは、最新のJavaScriptエンジンがプロパティアクセスを最適化する仕組み上、すべてのブラウザやJavaScriptエンジンにおいて、とても低速な操作となります。プロトタイプの継承関係を変更することによる性能上の影響は微細で広範囲にわたり、単にobj.__proto__ = ...という文の実行時間に留まらず、[[Prototype]]が変更されたいずれかのオブジェクトへのアクセスを持つあらゆるコードに及ぶ可能性があります。性能を気にしている場合、オブジェクトの[[Prototype]]の変更は避けるべきです。代わりに、Object.create()を使用して意図する[[Prototype]]をもつオブジェクトを新たに生成してください。

警告: Object.prototype.__proto__は現時点でほとんどのブラウザがサポートしていますが、そのプロパティの存在と正確な動作は、ウェブブラウザーの互換性を確保するためのレガシー機能として、ECMAScript 2015で初めて標準化されました。かわりにObject.getPrototypeOf()だけを使用することが推奨されます。

概要

Object.prototype__proto__プロパティは、アクセスされるオブジェクトの内部の[[Prototype]](オブジェクトまたはnullのどちらか)を暴露するアクセサプロパティ(getter関数とsetter関数)です。

__proto__の使用は、論争の的になり、推奨されていません。もともとEcmaScript言語仕様には含まれていませんでしたが、現在のブラウザでは結局それを実装しています。最近になってようやく、__proto__ プロパティはブラウザ間の互換性を保つためにECMAScript2015の言語仕様で標準化されました。従って、将来的にサポートされることになります。Object.getPrototypeOf/Reflect.getPrototypeOf 及び Object.setPrototypeOf/Reflect.setPrototypeOf は非推奨です。(オブジェクトの[[Prototype]]の設定は、性能を気にしている場合避けるべき低速の操作であるが)

また、__proto__プロパティは、生成時に[[Prototype]]オブジェクトを設定するためにObject.create()の代わりとしてもオブジェクトリテラルの定義で使用されます。参照: object initializer / literal syntax

構文

var shape = {};
var circle = new Circle();

// Set the object prototype.
// 非推奨。 参考用です。 実際のコードで使用しないでください。
shape.__proto__ = circle;

// Get the object prototype
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__ getter 関数はオブジェクトの内部の[[Prototype]]の値を外部にさらします。オブジェクトリテラルを使用して生成されたオブジェクトに対して、この値はObject.prototypeです。配列リテラルを使用して生成されたオブジェクトに対して、この値はArray.prototypeです。関数に対して、この値はFunction.prototypeです。new funを使用して生成されたオブジェクトの対して、この値はfun.prototypeです。ここで、funはJavaScript (ArrayBooleanDateNumberObjectString等 —JavaScriptの進化として追加された新しいコンストラクタを含みます。)によって提供されるビルトインコンストラクタ関数の一つです。new funを使用して生成されたオブジェクトに対して、この値は常にfun.prototypeの値です。ここで、funはスクリプトで定義された関数です。(すなわち、新しい値がfun.prototypeに割り当てられている場合、以前生成されたfunインスタンスも[[Prototype]]として新しい値を持ち、__proto__とfun.prototypeとして同じアドレスを参照します)。

__proto__ setterでオブジェクトの[[Prototype]]は変化することができます。オブジェクトは、Object.isExtensible()に応じて拡張可能である必要があります。: 拡張可能ではない場合、TypeErrorがスローされます。与えられた値はオブジェクト、または、nullである必要があります。他の値が与えられた場合は何もしません。

プロトタイプが継承のためにどのように使用されるかを理解するには、ガイド記事Inheritance and the prototype chainを参照してください。

__proto__ プロパティは、getter関数とsetter関数からなるObject.prototype 上の簡単なアクセスプロパティです。最終的にのObject.prototypeを参照する__proto__に対してのプロパティアクセスはこのプロパティを探します。しかし、Object.prototypeを参照しないアクセスはこのプロパティを探しません。Object.prototypeが参照される前にいくつかの他の__proto__プロパティが見つけられた場合、そのプロパティは、Object.prototype上で見つけられたプロパティを隠します。

仕様

仕様 状況 コメント
ECMAScript 2015 (6th Edition, ECMA-262)
Object.prototype.__proto__ の定義
標準 Webブラウザのために追加ECMAScript機能の(規定)附属書に含まれています(仕様が既に実装されているものを体系化することに注意してください)。

ブラウザ実装状況

注意: ES2015の仕様が、__proto__へのサポートがWebブラウザに必要であることを規定している間、(規範として奨励されていますが)他の環境では必要ではありません。コードがWebブラウザではない環境をサポートする必要がある場合、代わりに、Object.getPrototypeOf()Object.setPrototypeOf()を使用することが推奨されています。

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari
基本サポート (有) (有) 11 (有) (有)
機能 Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本サポート (有) (有) (有) (有) (有) (有)

関連情報

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

 このページの貢献者: kdex, TakashiHarano, mandel59, haruki-sugarsun, shide55
 最終更新者: kdex,