複雑で理解しにくいJavaScriptのプロトタイプチェーンを、シンプルな図にしてイメージしやすくしよう!という試みです。
今回は、組み込みのコンストラクタ関数Arrayを例にしています。
前提
用語 | 説明 |
---|---|
[[prototype]] | オブジェクトの継承元を指す隠しプロパティ。これにより、オブジェクトはプロトタイプチェーンを通じて親オブジェクトのプロパティやメソッドを継承する。Object.getPrototypeOf(obj) や __proto__ プロパティでアクセスできる。 |
prototype | コンストラクタ関数が持つプロパティ。コンストラクタ関数のprototypeに設定したオブジェクトは、自身のインスタンス生成時に[[prototype]]に格納される。 |
コンストラクタ関数 | ObjectやArrayなど、newでインスタンスを生成できる関数のこと。 |
プロトタイプチェーン図解
- Array.prototypeは[[prototype]]にObject.prototypeを持つ。
- Object.prototypeは[[prototype]]がnull。つまりプロトタイプチェーンの終着点。
- コンストラクタ関数Arrayのインスタンスであるnew Array()は、Array.prototypeを[[prototype]]に持つため、プロトタイプチェーンによってArray.prototypeとObject.prototypeのプロパティ&メソッドを使用できる。
- コンストラクタ関数ObjectやArrayは関数オブジェクトであるため、コンストラクタ関数Functionのインスタンスとして生成される。そのため、自身(ObjectやArray)の[[prototype]]にはFunction.prototypeを持つ。これは自身のprototypeが持つ[[prototype]]とは別物なことに注意。
まとめ
-
プロトタイプチェーンとは、オブジェクトが呼び出されたプロパティやメソッドを持っていない場合に、[[Prototype]] をたどって親のオブジェクトを探索する仕組み。
例:new Array(1,2,3).toString() では、まずtoStringがnew Array(1,2,3).[[prototype]](つまりArray.prototype)にあるかチェックされる。そこになければArray.prototype.[[prototype]](つまりObject.prototype)にあるかチェックされる。toStringはObject.prototypeのメソッドなので、ここで見つかり実行される。 -
ArrayやObject等のコンストラクタ関数のprototypeプロパティに設定したオブジェクトが、インスタンスの隠しプロパティ[[prototype]]に格納される。
例:Array.prototypeはnew Array().[[prototype]]に格納される。