前回、javascriptのクラスについて軽く書いたが今回は、prototypeについてメモ。
こちらを読めば理解が深まる「JavaScriptでオブジェクト指向プログラミング」
今回は、上記のオブジェクト指向プログラミングを読んでみて自分なりに理解した内容をメモる。ただ細かい内容は上記を参照。
プロトタイプにする利点
クラスを作成するときに必要なメンバ変数やメソッドを記述していくと思うが、インスタンス化すると、それぞれのインスタンスにメモリが確保される。そのため20ほどのメソッドがあるとインスタンス化で無駄にコピーされメモリを使ってしまう。
だったら、prototypeプロパティに追加することで無駄なメモリを防ぐことになる。
//無駄にメソッドを作ってあるクラス
var PrevClass = function(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.seyname = function() {
alert(this.name);
}
this.seyage = function() {
alert(this.age);
}
this.seysex = function() {
alert(this.sex);
}
}
//プロトタイプに追加した記述
var AfterClass = function(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
AfterClass.prototype.seyhello = function() {
alert(this.name);
}
AfterClass.prototype.seyage = function() {
alert(this.age);
}
AfterClass.prototype.seysex = function() {
alert(this.sex);
}
プロトタイプの参照によるメモリ節約とは
プロトタイプに追加したオブジェクトはどのように参照されるのか?
- インスタンス化されたときに、prototypeオブジェクトはコピーされないため、無駄なコピーはされない
- prototypeに対する暗黙の参照が行われるのは、読み込みの場合の時である。(prototypeに追加したプロパティやメソッドを読みだしたとき)
- インスタンスは、まず自身のプロパティを参照しようとする。もし、自身にそのプロパティがあれば、それを参照するが、もしない場合は元となるオブジェクトのprototypeに格納されたオブジェクトを検索する
という具合に基本はインスタンスにコピーされないので、もしインスタンスのプロパティを呼び出した時に存在しなければ、プロトタイプを検索しに行くので無駄にプロパティやメソッドをコピーしなくてすむのでメモリの節約になる。
プロトタイプのメンバ変数の変更
あるクラスのprototypeに格納されたオブジェクト・・メンバ変数などが変更になった場合にそのクラスの作られた複数のインスタンスすべてに影響があるかどうかについて実験してみた
上記をテストしていただくと分かるが、baseクラスのインスタンスist1からprototypeに設定したnameプロパティの値を設定してもist2のnameプロパティの値に影響がないことが分かる。
最初はbaseクラスのインスタンスist1とist2のnameプロパティはbaseクラスのprototypeオブジェクトを参照(暗黙の参照)しにいっているが「ist1.name=”xxxx”」と新たにist1にnameプロパティを設定したことになるのでist1はbaseクラスのprototypeオブジェクトを参照しに行く必要がなくなる。
インスタンスist2はbaseクラスのprototypeのnameを参照しに行っている。
と、、あまり書くと長くなるので、このくらいにして次回は継承などについて書こうかと思う。