JavaScriptのプロトタイプとプロトタイプチェーン
プロトタイプとは
- クラスのようなもの
- JacaScriptには「クラス」という概念がない
- (ES6ではクラスの概念ができたが普及は微妙)
prototypeプロパティ
- オブジェクトには、メンバを追加するためのprototypeプロパティが用意されている
- 意識して使わない限りは空のオブジェクトを参照している
- 何かを格納すると、オブジェクトをインスタンス化した先のオブジェクトに引き継ぐことができる
var Phone = function(name) { this.name = name; }; Phone.prototype.getName = function() { retrun this.name }; var featurePhone = new Phone('feature phone'); var smartPhone = new Phone('smart phone'); console.log(featurePhone.getName()); // feature phone console.log(smartPhone.getName()); // smart phone
prototypeプロパティを使って、オブジェクトにメソットを追加する例 プロパティに格納したメソッドが、インスタンス化したそれぞれのオブジェクトに引き継がれている。
なぜわざわざプロパティを使ってメソッドを定義するのか? コンストラクタの中に定義すれば良いのでは?
→ メモリ使用量の削減のため
prototypeプロパティがあれば * インスタンス化されたオブジェクトは、使用したコンストラクタのprototypeプロパティに対して暗黙の参照を持つ。 * prototypeプロパティに格納したメソッドにも暗黙の参照を持っているので、自前でメソッドを持つ必要がない。
これにより、無駄なメモリ消費が避けられる
もう一つのメリット
var Phone = function(name) { this.name = name; }; var featurePhone = new Phone('feature phone'); Phone.prototype.getName = function() { return this.name; }; var smartPhone = new Phone('smart phone'); console.log(featurePhone.getName()); // feature phone console.log(smartPhone.getName()); // smart phone
featurePhoneの生成を、prototypeプロパティにメソッドを追加する前に移動しても featurePhoneもgetNameメソッドを呼び出せている。 prototypeプロパティでメソッドおを管理すれば、インスタンスがオブジェクト(コンストラクタ)の変更をリアルタイムに認識できる
ここまでまとめ
- コンストラクタを定義する際には、メソッドは必ずprototypeプロパティで管理する
プロトタイプチェーン
JavaScriptでオブジェクト指向の継承を行うための仕組み
var Phone = function() {}; Phone.prototype = { getOwner: function() { console.log('Owner is', this.owner); } }; var SmartPhone function(owner) { this.owner = owner }; SmartPhone.prototype = new Phone(); // ① SmartPhone.prototype.tap = function() { console.log('tap!'); }; var myPhone = new SmartPhone('hatenai'); myPhone.getOwner(); // ② Owner is hatena myPhone.tap(); tap! var otherPhone = new SmartPhone('blog'); otherPhone.getOwner(); // Owner is blog otherPhone.tap(); // tap!
①がプロトタイプチェーン
継承したオブジェクトのインスタンスを、自身のprototypepプロパティに格納する
②におけるメンバ解決
- myPhoneオブジェクト自身のgetOwnerメソッドを探す
- 見つからないため、myPhoneのコンストラクタ(SmartPhoneオブジェクト)のプロトタイプ(Phoneオブジェクトのインスタンス)にgetOwnerメソッドを探しに行く
- PhoneオブジェクトのプロトタイプにてgetOwnerメソッドを発見する
まとめ
- プロトタイプチェーンが使いこなせれば、オブジェクト指向ライクな記述ができるようになる。