LoginSignup
29
25

More than 5 years have passed since last update.

JavaScriptのprototypeチェーンとはなんぞや

Last updated at Posted at 2017-09-22

はじめに

JavaScriptのメソッドなんかをググってる時に、よく以下のようなものを見ますよね。

Array_prototype_map___-_JavaScript___MDN.png

JSはよくprototypeベースな言語とか言われたりしていますが、prototypeとはなんぞやって疑問に思っていました。
特に今回はその中でも、prototypeチェーンに絞っています。

※もし間違いがあれば、指摘していただけると助かりますm(__)m

すべてのオブジェクトは __proto__ を保持している

以下のコードをブラウザのConsoleなどで実行して見てください。

sample.js
const dog = {}
console.log(dog)

生成されたオブジェクトdogの中身をconsole.logで確認すると、_proto_というプロパティが確認できますよね。

良い記事を書くためのガイドライン_-_Qiita_Support.png

結論を先に言いますと、全てのオブジェクトは、自動的に __proto__ プロパティを保持しています
ちなみに、 __proto__ プロパティもオブジェクトです。

__proto__ ってなんなのか

結論を先に言います。
オブジェクトの __proto__ プロパティはコンストラクタ関数のprototypeプロパティを参照している。

以下の画像を見てください。

良い記事を書くためのガイドライン_-_Qiita_Support.png

__proto__ は、Object.prototypeということがわかります。
これはつまり、dogの__proto__プロパティがObjectコンストラクタ関数のprototypeプロパティのオブジェクトを参照しているということです。

また、コンストラクタ関数は自動的にprototypeプロパティを保持しています。prototypeプロパティはオブジェクトです。

以下のコードで確認しておきましょう。

sample2.js
//コンストラクタ関数Humanを定義
function Human (name) {
  this.name = name;
}

//prototypeオブジェクトに関数をいれる
Human.prototype.hello = function () {
  return this.name + 'さん、こんにちは!';
}

var shin = new Human('shin');
console.log(shin.hello()); //=>shinさん、こんにちは!

ちょっと脱線したので、大事なことをまとめます。

内容
オブジェクト 全てのオブジェクトは__proto__プロパティを保持している。
また、__proto__プロパティはコンストラクタ関数のprototypeプロパティを参照している
コンストラクタ関数 prototypeプロパティを保持している

prototypeチェーンとは

まず、言葉で説明します。
prototypeチェーンとは、オブジェクトに必要なプロパティや関数がない場合、__proto__が参照するコンストラクタ関数のprototypeオブジェクトにさかのぼって探すことをいいます。

わかりづらいので、コードで見ていきましょう。

sample3.js
//オブジェクトを生成
const str = new String("");

console.log(str.__proto__ === String.prototype); //=>true

console.log(String.prototype.__proto__ === Object.prototype); //=>true

//prototypeチェーンの最終地点
console.log(Object.prototype.__proto__); //=>null

ここで重要なのは、prototypeプロパティもオブジェクトであるということです。
つまり、__proto__を保持していることになります。

図で表すと以下のようなイメージですね。

Screenshot from Gyazo

例えば、strに対して定義されていないメソッドやプロパティを呼び出すと、Stringコンストラクタ関数のprototypeプロパティを参照し、それでもなければStringコンストラクタ関数のprototypeオブジェクトが持っている__proto__が最終地点のObjectコンストラクタ関数のprototypeプロパティを参照します。それでもない場合は、Objectコンストラクタ関数のprototypeが持っている__proto__がnullが返却されます。

29
25
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
25