くまおの森

フロントエンドで学んだこと知ったことを自分なりに噛み砕いてメモしてく技術ブログ

【JavaScript】prototypeが何なのかをはっきりさせる

JavaScriptとはプロトタイプベースの言語ということですが、

「プロトタイプ」とは何だろう?

 ということで、メモしていこうと思います。

 

プロトタイプオブジェクトです。

プロトタイプは全てのオブジェクトに関連付けられています。
全てのオブジェクトはプロトタイプのプロパティを継承しています。

なので全てのオブジェクトは、プロトタイプのプロパティを使用することができます。
(※1 Object.prototypeのみプロトタイプを持ちません。)

 

ということで、まずプロトタイプを見てみます。

f:id:naoaru-28:20170531154017p:plain

ArrayオブジェクトのプロトタイプをchromeのConsoleで出力してみました。

Arrayオブジェクトが持つプロパティがダダダーっとあって、その一番下に__proto__:Objectというものがあります。
こいつがプロトタイプです。

では、プロトタイプはどんなプロパティを持っているのかを見ると、こんな感じです。

f:id:naoaru-28:20170531154753p:plain

因みに、※1 Object.prototypeのみプロトタイプを持ちません。ということを書きましたが、
Object.prototypeをConsoleで出力すると以下になります。

f:id:naoaru-28:20170531160352p:plain

一個上の画像のArrayの継承している__proto__と持ってるプロパティが同じ。
ということは、Object.prototypeこそがプロトタイプなんですね。

なので、全てのオブジェクトはObject.prototypeを継承しているとも言えます。

 

このプロトタイプのプロパティはコードを書く際、同じ処理を再利用したり、オリジナルに拡張したりすることに利用します。

このように、Hello name♡とコンソールで出力するhelloメソッドをHumanオブジェクトのプロトタイプのプロパティに追加します。

naninu自身にhelloがあるわけではなく、Humanのprototypeにhelloを入れたので、(今回だとHumanをインスタンス化した変数naninu)naninu.__proto__.helloにあります。
ですが、naninu.hello();で呼び出すことができます。

このようにプロトタイプのプロパティを連鎖的に探し出してくれます。
(naninu.__proto__にhelloがなければ、naninu.__proto__.__proto__を探して、なければnaninu.__proto__.__proto__.__proto__を探して・・・というようにプロトタイプのプロトタイプは...と自動的に探していきます。)

これをプロトタイプチェーンと言います。

 

・・・長くなってしまいましたが、最後にもう一つ。

プロトタイプを使うことで何が良いのかということです。以下ダメな例になります。

このように、直接コンストラクタ関数Humanにメソッドを追加することができますが、
このようにしてしまうと、Humanをnewでインスタンス化した分メソッドの処理も入ってることになります。

先ほど"同じ処理を再利用したり..."と書きましたが、これがそうです。

同じメソッドの処理を何個も作成することで、その分メモリ領域は使用され重くなっていってしまいますが、
プロトタイプを使用することで、処理はHuman.prototype.helloを参照するだけになり、使いまわすことができます。

プロトタイプって、

後での改良を見込んで、その仕事をする大筋として作る最初の模型。

(google検索)という意味なのでそういった目的でプロトタイプを追加していけば良いですね〜。